コード例 #1
0
        internal IOpcNode AddNode(IOpcNode parentNode, params string[] path)
        {
            var context = this.SystemContext;

            foreach (var name in path)
            {
                var childNode = (OpcInstanceNode)parentNode.Child(context, name);

                if (childNode == null)
                {
                    if (name[0] == '.')
                    {
                        childNode = new OpcDataVariableNode <int>(parentNode, name, DateTime.Now.Millisecond);
                    }
                    else
                    {
                        childNode = new OpcFolderNode(parentNode, name);
                    }

                    this.AddNode(context, childNode);

                    if (childNode is OpcVariableNode)
                    {
                        return(childNode);
                    }
                }

                parentNode = childNode;
            }

            return(parentNode);
        }
コード例 #2
0
        private OpcDataVariableNode <T[]> CreateArrayNode <T>(
            OpcFolderNode nodes,
            T defaultValue,
            Func <T, int, T> randomizer = null)
        {
            var value = Enumerable.Repeat(defaultValue, 5).ToArray();

            if (randomizer == null)
            {
                return(this.CreateNode(nodes, value, randomizer: null));
            }

            return(this.CreateNode(nodes, value, (oldValue, random) => {
                var index = this.indexRandom.Next(0, oldValue.Length - 1);

                ////var newValue = oldValue;

                // Array values need to be copied, otherwise there is no
                // Value-Changed-Bit set by the node.
                var newValue = new T[oldValue.Length];
                Array.Copy(oldValue, newValue, oldValue.Length);

                newValue[index] = randomizer(oldValue[index], random);
                return newValue;
            }));
        }
コード例 #3
0
        private OpcDataVariableNode <T> CreateNode <T>(
            OpcFolderNode nodes,
            T defaultValue,
            Func <T, int, T> randomizer = null)
        {
            var name = typeof(T).Name;

            name = char.ToUpper(name[0]) + name.Substring(1);

            if (typeof(T).IsArray)
            {
                name = typeof(T).GetElementType().Name + "Array";
            }

            var node = new OpcDataVariableNode <T>(nodes, name, defaultValue);

            node.ReadVariableValueCallback  = this.HandleReadVariableValue;
            node.WriteVariableValueCallback = this.HandleWriteVariableValue;

            if (randomizer != null)
            {
                this.tasks.Add(() => {
                    node.Value = randomizer(node.Value, this.valueRandom.Next(0, 183));
                    node.ApplyChanges(this.SystemContext);
                });
            }

            return(node);
        }
コード例 #4
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            var machineNode = new OpcObjectNode(this.DefaultNamespace.GetName("Machine"));

            this.jobsNode = new OpcFolderNode(machineNode, "Jobs");
            references.Add(machineNode, OpcObjectTypes.ObjectsFolder);

            // Add some predefined jobs.
            new OpcDataVariableNode <int>(this.jobsNode, "JOB01", value: 0);
            new OpcDataVariableNode <int>(this.jobsNode, "JOB02", value: 0);
            new OpcDataVariableNode <int>(this.jobsNode, "JOB03", value: 0);

            // Define a generic event to notify about job-scheduled.
            this.jobScheduldedEventNode          = new OpcEventNode(this.jobsNode, "JobSchedulded");
            this.jobScheduldedEventNode.Severity = OpcEventSeverity.Medium;
            this.jobScheduldedEventNode.Message  = "The job has been schedulded.";

            this.jobsNode.AddNotifier(this.SystemContext, this.jobScheduldedEventNode);

            // Define a generic event to notify about job-completed.
            this.jobCompletedEventNode          = new OpcEventNode(this.jobsNode, "JobCompleted");
            this.jobCompletedEventNode.Severity = OpcEventSeverity.Medium;
            this.jobCompletedEventNode.Message  = "The job has been completed.";

            this.jobsNode.AddNotifier(this.SystemContext, this.jobCompletedEventNode);
            return(new IOpcNode[] { machineNode });
        }
コード例 #5
0
        /// <summary>
        /// Creates the nodes provided and associated with the node manager.
        /// </summary>
        /// <param name="references">A dictionary used to determine the logical references between
        /// existing nodes (e.g. OPC default nodes) and the nodes provided by the node
        /// manager.</param>
        /// <returns>An enumerable containing the root nodes of the node manager.</returns>
        /// <remarks>This method will be only called once by the server on start up.</remarks>
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // It is necessary to assign to all root nodes one of the namespaces used to
            // identify one of the associated namespaces (see the ctor of the class). This
            // namespace does identify the node as member of the namespace of the node
            // manager. Optionally it is possible to assign namespace to the child nodes
            // too. But by default their missing namespace will be auto-completed through the
            // namespace of their parent node.
            var machineOne = new OpcFolderNode(this.DefaultNamespace.GetName("Machine_1"));

            // Add new reference to make the node visible beneath the ObjectsFolder
            // (the top most root node within every OPC UA server).
            references.Add(machineOne, OpcObjectTypes.ObjectsFolder);

            new OpcDataVariableNode <string>(machineOne, "Name", "Machine 1");
            new OpcDataVariableNode <byte>(machineOne, "Status", 1);

            this.positionHistorian = new OpcNodeHistorian(
                this, new OpcDataVariableNode <int>(machineOne, "Position", -1));

            SampleNodeManager.CreateHistoryEntries(this.positionHistorian);

            new OpcDataVariableNode <bool>(machineOne, "IsActive", true);
            new OpcDataVariableNode <double>(machineOne, "Temperature", 18.3);

            return(new IOpcNode[] { machineOne });
        }
コード例 #6
0
        /// <summary>
        /// Creates the nodes provided and associated with the node manager.
        /// </summary>
        /// <param name="references">A dictionary used to determine the logical references between
        /// existing nodes (e.g. OPC default nodes) and the nodes provided by the node
        /// manager.</param>
        /// <returns>An enumerable containing the root nodes of the node manager.</returns>
        /// <remarks>This method will be only called once by the server on start up.</remarks>
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // It is necessary to assign to all root nodes one of the namespaces used to
            // identify one of the associated namespaces (see the ctor of the class). This
            // namespace does identify the node as member of the namespace of the node
            // manager. Optionally it is possible to assign namespace to the child nodes
            // too. But by default their missing namespace will be auto-completed through the
            // namespace of their parent node.
            var machineOne = new OpcFolderNode(this.DefaultNamespace.GetName("Machine_1"));

            // Add new reference to make the node visible beneath the ObjectsFolder
            // (the top most root node within every OPC UA server).
            references.Add(machineOne, OpcObjectTypes.ObjectsFolder);

            new OpcDataVariableNode <string>(machineOne, "Name", "Machine 1");

            // Using an enumeration type which defines the necessary OpcDataType-Attribute and
            // that is defined as a custom data type node does not need more node setup to use
            // the custom data type like follows:
            new OpcDataVariableNode <MachineStatus>(machineOne, "Status", MachineStatus.Started);

            new OpcDataVariableNode <bool>(machineOne, "IsActive", true);

            // Ensure that the used enumeration type is defined as a data type node.
            return(new IOpcNode[] { machineOne, new OpcDataTypeNode <MachineStatus>() });
        }
コード例 #7
0
        public static void Main(string[] args)
        {
            var node = new OpcFolderNode("MyFolder");

            node.DisplayName = new OpcText("MyFolder", "en-US", "MyFolder.DisplayName");
            node.Description = new OpcText("MyFolder Description", "en-US", "MyFolder.Description");

            using (var server = new OpcServer("opc.tcp://localhost:4840", node)) {
                server.Globalization.AddResources(
                    "en-US",
                    new KeyValuePair <string, string>("MyFolder.DisplayName", "MyFolder (en)"),
                    new KeyValuePair <string, string>("MyFolder.Description", "MyFolder Description (en)"));
                server.Globalization.AddResources(
                    "de-DE",
                    new KeyValuePair <string, string>("MyFolder.DisplayName", "Mein Ordner (de)"),
                    new KeyValuePair <string, string>("MyFolder.Description", "Meine Ordner Beschreibung (de)"));
                server.Globalization.AddResources(
                    "fr-FR",
                    new KeyValuePair <string, string>("MyFolder.DisplayName", "Mon dossier (fr)"),
                    new KeyValuePair <string, string>("MyFolder.Description", "Description de mon dossier (fr)"));

                server.Start();

                Console.WriteLine("Server started - press any key to exit.");
                Console.ReadKey(true);
            }
        }
コード例 #8
0
        private void CreateMethodNodes(OpcFolderNode nodes)
        {
            var methodNodes = new OpcFolderNode(nodes, "Methods");

            new OpcMethodNode(methodNodes, "Add", new Func <int, int, int>(this.Add));
            new OpcMethodNode(methodNodes, "Divide", new Func <int, int, int>(this.Divide));
            new OpcMethodNode(methodNodes, "Multiply", new Func <int, int, int>(this.Multiply));
            new OpcMethodNode(methodNodes, "Power", new Func <int, int, int>(this.Power));
            new OpcMethodNode(methodNodes, "Subtract", new Func <int, int, int>(this.Substract));
        }
コード例 #9
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            var zementTech = new OpcFolderNode(new OpcName("ZementTech", this.DefaultNamespaceIndex));

            references.Add(zementTech, OpcObjectTypes.ObjectsFolder);

            var zementTechConfig = new OpcFolderNode(new OpcName("SimKonfiguration", this.DefaultNamespaceIndex));

            references.Add(zementTechConfig, OpcObjectTypes.ObjectsFolder);

            Context = this.SystemContext;

            AddConfig(zementTechConfig);

            RohMaterialGewinnung rohmaterialgewinnung = new RohMaterialGewinnung(zementTech, "Gewinnung", this.SystemContext);
            MotorDelayLane       brecher   = new MotorDelayLane(zementTech, "Brecher", this.SystemContext, 2);
            MotorDelayLane       transport = new MotorDelayLane(zementTech, "Transport", this.SystemContext, 4);
            Silo           mischbett       = new Silo(zementTech, "Mischbett", this.SystemContext, 45000.0);
            MotorDelayLane walzmühle       = new MotorDelayLane(zementTech, "Mühle", this.SystemContext, 1);
            Silo           rohmehlsilo     = new Silo(zementTech, "RohmehlSilo", this.SystemContext, 30000.0);

            Brennstoffzufuhr bsz          = new Brennstoffzufuhr(zementTech, "Brennstoffzufuhr", this.SystemContext);
            Drehrohrofen     drehrohrofen = new Drehrohrofen(zementTech, "Drehrohrofen", this.SystemContext, bsz);
            Zyklon           zyklon       = new Zyklon(zementTech, "Zyklon", this.SystemContext, drehrohrofen);

            Kuehler kuehler     = new Kuehler(zementTech, "Kühler", this.SystemContext);
            Silo    klinkerSilo = new Silo(zementTech, "KlinkerSilo", this.SystemContext, 20000.0);

            MotorDelayLane zementMühle = new MotorDelayLane(zementTech, "Zementmühle", this.SystemContext, 1);
            Silo           zementSilo  = new Silo(zementTech, "ZementSilo", this.SystemContext, 35000.0);

            Absackung absackung = new Absackung(zementTech, "Absackung", this.SystemContext);

            rohmaterialgewinnung.Receiver = brecher;
            brecher.Receiver      = transport;
            transport.Receiver    = mischbett;
            mischbett.Receiver    = walzmühle;
            walzmühle.Receiver    = rohmehlsilo;
            rohmehlsilo.Receiver  = zyklon;
            zyklon.Receiver       = drehrohrofen;
            drehrohrofen.Receiver = kuehler;
            kuehler.Receiver      = klinkerSilo;
            klinkerSilo.Receiver  = zementMühle;
            zementMühle.Receiver  = zementSilo;
            zementSilo.Receiver   = absackung;

            return(new IOpcNode[]
            {
                zementTech,
                zementTechConfig,
                new OpcDataTypeNode <OperationState>(),
                new OpcDataTypeNode <OperationMode>(),
                new OpcDataTypeNode <TimeMultiplier>()
            });
        }
コード例 #10
0
        private static OpcFolderNode CreateDataNode()
        {
            var dataNode = new OpcFolderNode("Data");

            for (int index = 0; index < NumberOfNodes; index++)
            {
                dataNodes.Add(new OpcDataVariableNode <int>(dataNode, $"Var{index:00000}", value: index));
            }

            timestampNode = new OpcDataVariableNode <DateTime>(dataNode, "Timestamp");
            return(dataNode);
        }
コード例 #11
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // Define custom root node.
            var FDANode = new OpcFolderNode(new OpcName("FDA", this.DefaultNamespaceIndex));

            // Add custom root node to the Objects-Folder (the root of all server nodes):
            references.Add(FDANode, OpcObjectTypes.ObjectsFolder);

            // Add custom sub node beneath of the custom root node:
            //var isMachineRunningNode = new OpcDataVariableNode<bool>(FDANode, "IsRunning");

            // Return each custom root node using yield return.
            yield return(FDANode);
        }
コード例 #12
0
        internal IOpcNode AddRootNode(params string[] path)
        {
            var newNode = new OpcFolderNode(path[0].TrimStart('$'));

            var reference = OpcNodeReference.To(OpcObjectTypes.ObjectsFolder);

            this.AddNode(this.SystemContext, newNode, reference);

            if (path.Length > 1)
            {
                return(this.AddNode(newNode, path.Skip(1).ToArray()));
            }

            return(newNode);
        }
コード例 #13
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            var nodes = new OpcFolderNode(this.DefaultNamespace.GetName("Nodes"));

            references.Add(nodes, OpcObjectTypes.ObjectsFolder);

            yield return(nodes);

            this.CreateStaticNodes(nodes);
            this.CreateDynamicNodes(nodes);
            this.CreateMethodNodes(nodes);

            yield return(new OpcDataTypeNode <MyEnum>());

            yield return(new OpcDataTypeNode <MyEnumFlags>());
        }
コード例 #14
0
        private static OpcFolderNode CreateDataNode()
        {
            var dataNode = new OpcFolderNode("Data");

            dataAvailableNode = new OpcDataVariableNode <bool>(dataNode, "DataAvailable");

            dataProcessedNode = new OpcDataVariableNode <bool>(dataNode, "DataProcessed");
            dataProcessedNode.WriteVariableValueCallback = WriteDataProcessed;

            for (int index = 0; index < NumberOfNodes; index++)
            {
                dataNodes.Add(new OpcDataVariableNode <int>(dataNode, $"Var{index:00000}", value: index));
            }

            timestampNode = new OpcDataVariableNode <DateTime>(dataNode, "Timestamp");
            return(dataNode);
        }
コード例 #15
0
        private void CreateStaticNodes(OpcFolderNode nodes)
        {
            var staticNodes = new OpcFolderNode(nodes, "Static");

            this.CreateNode <byte>(staticNodes, 1);
            this.CreateArrayNode <byte>(staticNodes, 1);

            this.CreateNode <sbyte>(staticNodes, 2);
            this.CreateArrayNode <sbyte>(staticNodes, 2);

            this.CreateNode <short>(staticNodes, 3);
            this.CreateArrayNode <short>(staticNodes, 3);

            this.CreateNode <ushort>(staticNodes, 4);
            this.CreateArrayNode <ushort>(staticNodes, 4);

            this.CreateNode <int>(staticNodes, 5);
            this.CreateArrayNode <int>(staticNodes, 5);

            this.CreateNode <uint>(staticNodes, 6u);
            this.CreateArrayNode <uint>(staticNodes, 6u);

            this.CreateNode <long>(staticNodes, 7L);
            this.CreateArrayNode <long>(staticNodes, 7L);

            this.CreateNode <ulong>(staticNodes, 8u);
            this.CreateArrayNode <ulong>(staticNodes, 8u);

            this.CreateNode <float>(staticNodes, 9.10f);
            this.CreateArrayNode <float>(staticNodes, 9.10f);

            this.CreateNode <double>(staticNodes, 11.12);
            this.CreateArrayNode <double>(staticNodes, 11.12);

            var stringValue = this.RandomString();

            this.CreateNode <string>(staticNodes, stringValue);
            this.CreateArrayNode <string>(staticNodes, stringValue);

            this.CreateNode <MyEnum>(staticNodes, MyEnum.Maintenance);
            //this.CreateArrayNode<MyEnum>(staticNodes, MyEnum.Starting);

            this.CreateNode <MyEnumFlags>(staticNodes, MyEnumFlags.CanCut | MyEnumFlags.CanFold);
            //this.CreateArrayNode<MyEnumFlags>(staticNodes, MyEnumFlags.CanPrint | MyEnumFlags.CanCorrugate);
        }
コード例 #16
0
        private void CreateDynamicNodes(OpcFolderNode nodes)
        {
            var dynamicNodes = new OpcFolderNode(nodes, "Dynamic");

            this.CreateNode <byte>(dynamicNodes, 1, (old, random) => unchecked ((byte)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <byte>(dynamicNodes, 1, (old, random) => unchecked ((byte)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <sbyte>(dynamicNodes, 2, (old, random) => unchecked ((sbyte)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <sbyte>(dynamicNodes, 2, (old, random) => unchecked ((sbyte)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <short>(dynamicNodes, 3, (old, random) => unchecked ((short)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <short>(dynamicNodes, 3, (old, random) => unchecked ((short)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <ushort>(dynamicNodes, 4, (old, random) => unchecked ((ushort)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <ushort>(dynamicNodes, 4, (old, random) => unchecked ((ushort)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <int>(dynamicNodes, 5, (old, random) => unchecked ((int)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <int>(dynamicNodes, 5, (old, random) => unchecked ((int)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <uint>(dynamicNodes, 6u, (old, random) => unchecked ((uint)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <uint>(dynamicNodes, 6u, (old, random) => unchecked ((uint)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <long>(dynamicNodes, 7L, (old, random) => unchecked ((long)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <long>(dynamicNodes, 7L, (old, random) => unchecked ((long)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <ulong>(dynamicNodes, 8u, (old, random) => unchecked ((ulong)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <ulong>(dynamicNodes, 8u, (old, random) => unchecked ((ulong)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <float>(dynamicNodes, 9.10f, (old, random) => unchecked ((float)(DateTime.Now.Second * random) / (int)Math.Max((int)old, 1)));
            this.CreateArrayNode <float>(dynamicNodes, 9.10f, (old, random) => unchecked ((float)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            this.CreateNode <double>(dynamicNodes, 11.12, (old, random) => unchecked ((double)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));
            this.CreateArrayNode <double>(dynamicNodes, 11.12, (old, random) => unchecked ((double)(DateTime.Now.Second * random / (int)Math.Max((int)old, 1))));

            var stringValue = this.RandomString();

            this.CreateNode <string>(dynamicNodes, stringValue, this.RandomString);
            this.CreateArrayNode <string>(dynamicNodes, stringValue, this.RandomString);

            this.CreateNode <MyEnum>(dynamicNodes, MyEnum.Starting, this.RandomEnum);
            //this.CreateArrayNode<MyEnum>(dynamicNodes, MyEnum.Maintenance, this.RandomEnum);

            this.CreateNode <MyEnumFlags>(dynamicNodes, MyEnumFlags.CanCut | MyEnumFlags.CanLaminate, this.RandomEnum);
            //this.CreateArrayNode<MyEnumFlags>(dynamicNodes, MyEnumFlags.CanFold | MyEnumFlags.CanPrint, this.RandomEnum);
        }
コード例 #17
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            _matlabFolder = new OpcFolderNode(
                new OpcName(MatlabFolderName, this.DefaultNamespaceIndex));


            references.Add(_matlabFolder, OpcObjectTypes.ObjectsFolder);
            MyDeleagate del = UpdateVariables;

            new OpcMethodNode(_matlabFolder, GetVariablesMethod, del);
            var v = new OpcDataVariableNode <int>(_matlabFolder, new OpcName("GetVariablesVariable"), 0);//new OpcVariableNode(_matlabFolder,new OpcName("GetVariablesVariable"), 0);

            v.WriteVariableValueCallback = WriteVariableValueCallback;
            v.AccessLevel = OpcAccessLevel.CurrentReadOrWrite;
            Console.WriteLine();
            UpdateVariables();

            return(new IOpcNode[] { _matlabFolder });
        }
コード例 #18
0
        public static void Main(string[] args)
        {
            producerControl = new CancellationTokenSource();

            dataNodes = new List <OpcDataVariableNode <int> >();
            dataNode  = CreateDataNode();

            var producer = new Thread(ProduceDataChanges);

            using (var server = new OpcServer("opc.tcp://localhost:4840/", dataNode)) {
                server.Start();
                producer.Start(server);

                Console.WriteLine("Server started - press any key to exit.");
                Console.ReadKey(true);

                producerControl.Cancel();
                producer.Join();
            }
        }
コード例 #19
0
        public static void Main(string[] args)
        {
            OpcNodeId.Factory = new SimaticNodeIdFactory();

            var db1 = new OpcFolderNode(
                "DataBlock1",
                new OpcDataVariableNode <byte>("MaxByte", value: byte.MaxValue),
                new OpcDataVariableNode <short>("MaxInt", value: short.MaxValue),
                new OpcDataVariableNode <int>("MaxDInt", value: int.MaxValue));

            var db2 = new OpcFolderNode(
                "DataBlock2",
                new OpcObjectNode("MyStruct",
                                  new OpcDataVariableNode <int>("FieldA", value: 10),
                                  new OpcDataVariableNode <int>("FieldB", value: 20)));

            using (var server = new OpcServer("opc.tcp://localhost:4840/", db1, db2)) {
                server.Start();

                Console.WriteLine("Server started - press any key to exit.");
                Console.ReadKey(true);
            }
        }
コード例 #20
0
        /// <summary>
        /// Creates the nodes provided and associated with the node manager.
        /// </summary>
        /// <param name="references">A dictionary used to determine the logical references between
        /// existing nodes (e.g. OPC default nodes) and the nodes provided by the node
        /// manager.</param>
        /// <returns>An enumerable containing the root nodes of the node manager.</returns>
        /// <remarks>This method will be only called once by the server on start up.</remarks>
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // It is necessary to assign to all root nodes one of the namespaces used to
            // identify one of the associated namespaces (see the ctor of the class). This
            // namespace does identify the node as member of the namespace of the node
            // manager. Optionally it is possible to assign namespace to the child nodes
            // too. But by default their missing namespace will be auto-completed through the
            // namespace of their parent node.
            var machineOne = new OpcFolderNode(this.DefaultNamespace.GetName("Machine_1"));

            // Add new reference to make the node visible beneath the ObjectsFolder
            // (the top most root node within every OPC UA server).
            references.Add(machineOne, OpcObjectTypes.ObjectsFolder);

            new OpcDataVariableNode <string>(machineOne, "Name", "Machine 1");
            new OpcDataVariableNode <byte>(machineOne, "Status", 1);

            new OpcDataVariableNode <bool>(machineOne, "IsActive", true);

            // The mapping of the UNECE codes to OPC UA (OpcEngineeringUnitInfo.UnitId) is available here:
            // http://www.opcfoundation.org/UA/EngineeringUnits/UNECE/UNECE_to_OPCUA.csv

            var pressureNode = new OpcAnalogItemNode <double>(machineOne, "Pressure", 2.116);

            pressureNode.InstrumentRange      = new OpcValueRange(230.11315);
            pressureNode.EngineeringUnit      = new OpcEngineeringUnitInfo(4732211, "kg/bar", "kilogram per bar");
            pressureNode.EngineeringUnitRange = new OpcValueRange(120.0);

            var temperatureNode = new OpcAnalogItemNode <double>(machineOne, "Temperature", 18.3);

            temperatureNode.InstrumentRange      = new OpcValueRange(80.0, -40.0);
            temperatureNode.EngineeringUnit      = new OpcEngineeringUnitInfo(4408652, "°C", "degree Celsius");
            temperatureNode.EngineeringUnitRange = new OpcValueRange(70.8, 5.0);

            return(new IOpcNode[] { machineOne });
        }
コード例 #21
0
        /// <summary>
        /// Creates the nodes provided and associated with the node manager.
        /// </summary>
        /// <param name="references">A dictionary used to determine the logical references between
        /// existing nodes (e.g. OPC default nodes) and the nodes provided by the node
        /// manager.</param>
        /// <returns>An enumerable containing the root nodes of the node manager.</returns>
        /// <remarks>This method will be only called once by the server on start up.</remarks>
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // It is necessary to assign to all root nodes one of the namespaces used to
            // identify one of the associated namespaces (see the ctor of the class). This
            // namespace does identify the node as member of the namespace of the node
            // manager. Optionally it is possible to assign namespace to the child nodes
            // too. But by default their missing namespace will be auto-completed through the
            // namespace of their parent node.
            var machineOne = new OpcFolderNode(this.DefaultNamespace.GetName("Machine_1"));

            // In case a client requests a condition referesh it queries the current event
            // information which is gathered using the CreateEvent method from each active
            // and retained alarm nodes.
            machineOne.QueryEventsCallback = (context, events) => {
                // Ensure that an re-entrance upon notifier cross-references will not add
                // events to the collection which are already stored in.
                if (events.Count != 0)
                {
                    return;
                }

                if (this.statusChangeNode.IsRetained)
                {
                    events.Add(this.statusChangeNode.CreateEvent(context));
                }

                if (this.positionLimitNode.IsRetained)
                {
                    events.Add(this.positionLimitNode.CreateEvent(context));
                }

                if (this.temperatureCriticalNode.IsRetained)
                {
                    events.Add(this.temperatureCriticalNode.CreateEvent(context));
                }
            };

            // Add new reference to make the node visible beneath the ObjectsFolder
            // (the top most root node within every OPC UA server).
            references.Add(machineOne, OpcObjectTypes.ObjectsFolder);

            new OpcDataVariableNode <string>(machineOne, "Name", "Machine 1");
            this.isActiveNode = new OpcDataVariableNode <bool>(machineOne, "IsActive", true);

            //// An alarm node have to be a notifier for another node or for the whole server.
            //// Is a alarm a notifier of another node:
            //// -> this node (the notified one) needs to be subscribed by the client to receive
            ////    the alarm data.
            //// Is a alarm a notifier of the whole server:
            //// -> the OpcObjectTypes.Server needs to be subscribed by the client to receive
            ////    the alarm data.

            // Machine 1, Status nodes setup
            {
                this.statusNode = new OpcDataVariableNode <byte>(machineOne, "Status", 1);

                // Define an alarm used to request a dialog which requires a dedicated response
                // action by a client. This kind of node can be used for service / operator tasks.
                this.statusChangeNode = new OpcDialogConditionNode(machineOne, "StatusChange");
                this.statusChangeNode.AutoReportChanges = true;

                this.statusChangeNode.Message         = "Operator requested";
                this.statusChangeNode.Prompt          = "The job has been finished, continue with the next one?";
                this.statusChangeNode.ResponseOptions = new OpcText[] { "Yes", "No" };
                this.statusChangeNode.DefaultResponse = 0;
                this.statusChangeNode.CancelResponse  = 1;
                this.statusChangeNode.OkResponse      = 0;

                // Handle any client response on an active dialog through applying the response
                // using RespondDialog and configuring the dialog as inactive.
                this.statusChangeNode.RespondCallback = (context, response) => {
                    this.isActiveNode.Value = (response == this.statusChangeNode.OkResponse);
                    this.isActiveNode.ApplyChanges(context);

                    this.statusChangeNode.RespondDialog(context, response);

                    this.statusChangeNode.Message    = "No operator required";
                    this.statusChangeNode.IsRetained = false;

                    return(OpcStatusCode.Good);
                };

                // Define the alarm as the notifier of the machineOne node.
                machineOne.AddNotifier(this.SystemContext, this.statusChangeNode);
            }

            // Machine 1, Position nodes setup
            {
                this.positionNode = new OpcAnalogItemNode <int>(machineOne, "Position", -1);
                this.positionNode.InstrumentRange      = new OpcValueRange(low: 120, high: 1);
                this.positionNode.EngineeringUnit      = new OpcEngineeringUnitInfo(4732211, "mm", "millimetre");
                this.positionNode.EngineeringUnitRange = new OpcValueRange(byte.MaxValue);

                // Define an alarm used to indicate the reaching of one or more limits during
                // a progress. Such limits may be predefined or progress dependent.
                this.positionLimitNode = new OpcExclusiveLimitAlarmNode(
                    machineOne, "PositionLimit", OpcLimitAlarmStates.All);

                this.positionLimitNode.HighHighLimit = 120; // e.g. mm
                this.positionLimitNode.HighLimit     = 100; // e.g. mm
                this.positionLimitNode.LowLimit      = 5;   // e.g. mm
                this.positionLimitNode.LowLowLimit   = 1;   // e.g. mm

                this.positionLimitNode.Message     = "No range problems";
                this.positionLimitNode.ReceiveTime = DateTime.UtcNow;

                this.positionLimitNode.AcknowledgeCallback = (context, eventId, comment) => {
                    this.positionLimitNode.Message = "Acknowledged with " + comment;
                    return(OpcStatusCode.Good);
                };

                // Define the alarm as the notifier of the machineOne node.
                machineOne.AddNotifier(this.SystemContext, this.positionLimitNode);
            }

            // Machine 1, Temperature nodes setup
            {
                this.temperatureNode = new OpcAnalogItemNode <double>(machineOne, "Temperature", 18.3);
                this.temperatureNode.InstrumentRange      = new OpcValueRange(80.0, -40.0);
                this.temperatureNode.EngineeringUnit      = new OpcEngineeringUnitInfo(4408652, "°C", "degree Celsius");
                this.temperatureNode.EngineeringUnitRange = new OpcValueRange(70.8, 5.0);

                // Define an alarm which just indicates the fulfillment of an alarm associated
                // condition. Such simple alarms only notify about the fulfillment without to
                // define additional prerequisites defined by the alarm itself. Much more
                // specialized alarms are subclasses of this type of alarm node.
                this.temperatureCriticalNode = new OpcAlarmConditionNode(machineOne, "TemperatureCritical");

                // Define the alarm as the notifier of the machineOne node.
                machineOne.AddNotifier(this.SystemContext, this.temperatureCriticalNode);

                // Define the alarm as the notifier of the whole Server node.
                this.AddNotifierNode(this.temperatureCriticalNode);
            }

            return(new IOpcNode[] { machineOne });
        }
コード例 #22
0
        /// <summary>
        /// Creates the nodes provided and associated with the node manager.
        /// </summary>
        /// <param name="references">A dictionary used to determine the logical references between
        /// existing nodes (e.g. OPC default nodes) and the nodes provided by the node
        /// manager.</param>
        /// <returns>An enumerable containing the root nodes of the node manager.</returns>
        /// <remarks>This method will be only called once by the server on start up.</remarks>
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            yield return(new OpcDataTypeNode <MachineStatus>());

            yield return(new OpcDataTypeNode <MachineSetup>());

            yield return(new OpcDataTypeNode <MachineJob>());

            yield return(new OpcDataTypeNode <ManufacturingOrder>());

            var machines = new OpcFolderNode("Machines");

            // Add new reference to make the node visible beneath the ObjectsFolder
            // (the top most root node within every OPC UA server).
            references.Add(machines, OpcObjectTypes.ObjectsFolder);

            var machineOne = new OpcFolderNode(machines, "Machine_1");

            new OpcDataVariableNode <string>(machineOne, "Name", "Machine 1");
            new OpcDataVariableNode <MachineStatus>(machineOne, "Status", MachineStatus.Stopped);
            new OpcDataVariableNode <bool>(machineOne, "IsActive", false);
            new OpcDataVariableNode <double>(machineOne, "Temperature", 18.3);
            new OpcMethodNode(machineOne, "StartJob", new Action <MachineJob>(job => Console.WriteLine(job.Number)));
            new OpcDataVariableNode <MachineJob>(machineOne, "Job", new MachineJob()
            {
                Number            = "JOB001",
                EstimatedDuration = 12500,
                InProcess         = false,
                CuttingPositions  = new int[] { 1000, 1500, 1570, 2020 },
                RequiredSetup     = MachineSetup.Packager,
                ScheduleTime      = DateTime.UtcNow.AddMinutes(10)
            });

            var machineTwo = new OpcFolderNode(machines, "Machine_2");

            new OpcDataVariableNode <string>(machineTwo, "Name", "Machine 2");
            new OpcDataVariableNode <MachineStatus>(machineTwo, "Status", MachineStatus.Suspended);
            new OpcDataVariableNode <bool>(machineTwo, "IsActive", true);
            new OpcDataVariableNode <double>(machineTwo, "Temperature", 20.7);
            new OpcMethodNode(machineOne, "StartJob", new Action <MachineJob>(job => Console.WriteLine(job.Number)));
            new OpcDataVariableNode <ManufacturingOrder>(machineTwo, "Order", new ManufacturingOrder()
            {
                Order   = "2020.10.10001",
                Article = "ART10025",
                Jobs    = new [] {
                    new MachineJob {
                        Number            = "JOB1001",
                        Duration          = 900,
                        EstimatedDuration = 1000,
                        InProcess         = false,
                        CuttingPositions  = new int[4],
                        RequiredSetup     = MachineSetup.Corrugator,
                        ScheduleTime      = DateTime.UtcNow
                    },
                    new MachineJob {
                        Number            = "JOB1002",
                        Duration          = 510,
                        EstimatedDuration = 500,
                        InProcess         = true,
                        CuttingPositions  = new int[] { 100, 1300, 1700, 2520 },
                        RequiredSetup     = MachineSetup.Cutter,
                        ScheduleTime      = DateTime.UtcNow.AddSeconds(1)
                    },
                    new MachineJob {
                        Number            = "JOB1003",
                        Duration          = 1030,
                        EstimatedDuration = 2200,
                        InProcess         = true,
                        CuttingPositions  = new int[4],
                        RequiredSetup     = MachineSetup.Printer1,
                        ScheduleTime      = DateTime.UtcNow.AddSeconds(2)
                    }
                }
            });

            yield return(machines);
        }
コード例 #23
0
        /// <summary>
        /// Creates the nodes provided and associated with the node manager.
        /// </summary>
        /// <param name="references">A dictionary used to determine the logical references between
        /// existing nodes (e.g. OPC default nodes) and the nodes provided by the node
        /// manager.</param>
        /// <returns>An enumerable containing the root nodes of the node manager.</returns>
        /// <remarks>This method will be only called once by the server on start up.</remarks>
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // It is necessary to assign to all root nodes one of the namespaces used to
            // identify one of the associated namespaces (see the ctor of the class). This
            // namespace does identify the node as member of the namespace of the node
            // manager. Optionally it is possible to assign namespace to the child nodes
            // too. But by default their missing namespace will be auto-completed through the
            // namespace of their parent node.
            var methods = new OpcFolderNode("Methods");

            // Add new reference to make the node visible beneath the ObjectsFolder
            // (the top most root node within every OPC UA server).
            references.Add(methods, OpcObjectTypes.ObjectsFolder);

            {
                var methodsByDelegate = new OpcFolderNode(methods, "Delegates");

                // Define a method node using an existing generic delegate type receiving information
                // about the context within the method is being called by a client.
                new OpcMethodNode(
                    methodsByDelegate,
                    "Add",
                    new Func <OpcMethodContext, int, int, int>(AddByDelegate));

                // Define a method node using a custom / specific delegate type receiving information
                // about the context within the method is being called by a client.
                new OpcMethodNode(
                    methodsByDelegate,
                    "Add2",
                    new AddDelegate(AddByDelegate));

                // Define a method node using an existing generic delegate type without receiving
                // information about the context within the method is being called by a client.
                new OpcMethodNode(
                    methodsByDelegate,
                    "Multiply",
                    new Func <int, int, int>(MultiplyByDelegate));

                // Define a method node using a custom / specific delegate type without receiving
                // information about the context within the method is being called by a client.
                new OpcMethodNode(
                    methodsByDelegate,
                    "Multiply2",
                    new MultiplyDelegate(MultiplyByDelegate));

                {
                    var moreMethods = new OpcFolderNode(methodsByDelegate, "More");

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessInputs",
                        new Action <int, string>(ProcessInputs));

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessInputsWithMetadata",
                        new Action <int, string>(ProcessInputsWithMetadata));



                    new OpcMethodNode(
                        moreMethods,
                        "ProcessOutputs",
                        new ProcessOutputsDelegate(ProcessOutputs));

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessOutputsWithMetadata",
                        new ProcessOutputsDelegate(ProcessOutputsWithMetadata));



                    new OpcMethodNode(
                        moreMethods,
                        "ProcessMultipleOutputs",
                        new ProcessMultipleOutputsDelegate(ProcessMultipleOutputs));

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessMultipleOutputsWithMetadata",
                        new ProcessMultipleOutputsDelegate(ProcessMultipleOutputsWithMetadata));



                    new OpcMethodNode(
                        moreMethods,
                        "ProcessInOutputs",
                        new ProcessInOutputsDelegate(ProcessInOutputs));

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessInOutputsWithMetadata",
                        new ProcessInOutputsDelegate(ProcessInOutputsWithMetadata));



                    new OpcMethodNode(
                        moreMethods,
                        "ProcessMultipleInOutputs",
                        new ProcessMultipleInOutputsDelegate(ProcessMultipleInOutputs));

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessMultipleInOutputsWithMetadata",
                        new ProcessMultipleInOutputsDelegate(ProcessMultipleInOutputsWithMetadata));



                    new OpcMethodNode(
                        moreMethods,
                        "ProcessWithContext",
                        new Action <OpcMethodContext>(ProcessWithContext));

                    new OpcMethodNode(
                        moreMethods,
                        "ProcessWithoutContext",
                        new Action(ProcessWithoutContext));
                }
            }

            {
                var methodsByCommand = new OpcFolderNode(methods, "Commands");

                // Define a method node using a method to that the call is to be delegated while
                // receiving information about the context of the call.
                new OpcMethodNode(
                    methodsByCommand,
                    "Add",
                    new OpcMethodDelegateCommand(AddByCommand),
                    inputArguments: new[] {
                    new OpcArgument("a", OpcDataType.Int32),
                    new OpcArgument("b", OpcDataType.Int32)
                },
                    outputArguments: new[] {
                    new OpcArgument("result", OpcDataType.Int32)
                });

                // Define a method node using a custom command instance to that the call is to be
                // delegated while receiving information about the context of the call.
                new OpcMethodNode(
                    methodsByCommand,
                    "Add2",
                    new AddCommand(),
                    inputArguments: new[] {
                    new OpcArgument("a", OpcDataType.Int32),
                    new OpcArgument("b", OpcDataType.Int32)
                },
                    outputArguments: new[] {
                    new OpcArgument("result", OpcDataType.Int32)
                });

                // Define a method node using a method to that the call is to be delegated while
                // receiving information about the context of the call.
                new OpcMethodNode(
                    methodsByCommand,
                    "Multiply",
                    new OpcMethodDelegateCommand(MultiplyByCommand),
                    inputArguments: new[] {
                    new OpcArgument("a", OpcDataType.Int32),
                    new OpcArgument("b", OpcDataType.Int32)
                },
                    outputArguments: new[] {
                    new OpcArgument("result", OpcDataType.Int32)
                });

                // Define a method node using a custom command instance to that the call is to be
                // delegated while receiving information about the context of the call.
                new OpcMethodNode(
                    methodsByCommand,
                    "Multiply2",
                    new MultiplyCommand(),
                    inputArguments: new[] {
                    new OpcArgument("a", OpcDataType.Int32),
                    new OpcArgument("b", OpcDataType.Int32)
                },
                    outputArguments: new[] {
                    new OpcArgument("result", OpcDataType.Int32)
                });
            }

            return(new IOpcNode[] { methods });
        }
コード例 #24
0
 public NodeManager(string name)
     : base($"http://sampleserver/{name.ToLower()}")
 {
     this.Name     = name;
     this.rootNode = new OpcFolderNode(this.DefaultNamespace.GetName(name));
 }
コード例 #25
0
 public NodeManager()
     : base("http://sampleserver/dynamicnodes")
 {
     this.rootNode = new OpcFolderNode(this.DefaultNamespace.GetName("Root"));
 }