Пример #1
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 });
        }
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            var variableNodes = new OpcObjectNode("MyVariables");

            references.Add(variableNodes, OpcObjectTypes.ObjectsFolder);

            var simpleVariableNodes = new OpcObjectNode(variableNodes, "Simple");

            new MySimpleVariableNode(simpleVariableNodes, "Var01", 1);
            new MySimpleVariableNode(simpleVariableNodes, "Var02", 2);

            var complexVariableNodes = new OpcObjectNode(variableNodes, "Complex");

            new MyComplexVariableNode(complexVariableNodes, "Var01", "A");
            new MyComplexVariableNode(complexVariableNodes, "Var02", "B", 42);

            var objectNodes = new OpcObjectNode("MyObjects");

            references.Add(objectNodes, OpcObjectTypes.ObjectsFolder);

            var simpleObjectNodes = new OpcObjectNode(objectNodes, "Simple");

            new MySimpleObjectNode(simpleObjectNodes, "Object01");
            new MySimpleObjectNode(simpleObjectNodes, "Object02");

            var complexObjectNodes = new OpcObjectNode(objectNodes, "Complex");

            new MyComplexObjectNode(complexObjectNodes, "Object01");
            new MyComplexObjectNode(complexObjectNodes, "Object02");

            return(new[] { variableNodes, objectNodes });
        }
Пример #3
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>() });
        }
Пример #4
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 });
        }
Пример #5
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            this.machineToolAlarmNode = new MachineToolAlarmConditionNode();
            this.alertsNode.AddNotifier(this.SystemContext, this.machineToolAlarmNode);

            yield return(this.machineToolAlarmNode);
        }
Пример #6
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            // We just want to define a simple "entry point" for client added nodes.
            var machineNode = new OpcObjectNode(this.DefaultNamespace.GetName("Machine"));

            references.Add(machineNode, OpcObjectTypes.ObjectsFolder);

            return(new IOpcNode[] { machineNode });
        }
Пример #7
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>()
            });
        }
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            foreach (var character in this.Name)
            {
                var value = (int)character;
                new OpcDataVariableNode <int>(this.rootNode, name: $"Var{value * 100}", value: value);
            }

            references.Add(this.rootNode, OpcObjectTypes.ObjectsFolder);
            yield return(this.rootNode);
        }
Пример #9
0
        protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
        {
            var machineNode = new OpcObjectNode(this.DefaultNamespace.GetName("Machine"));

            new VariableNode <int>(this, machineNode, "Status", value: 42);
            new VariableNode <string>(this, machineNode, "Job", value: "JOB-0543");

            new VariableNode <bool>(this, machineNode, "Shutdown", value: false);
            new VariableNode <short>(this, machineNode, "Speed", value: 1000);
            new VariableNode <string>(this, machineNode, "Tooling", value: "cutter");

            references.Add(machineNode, OpcObjectTypes.ObjectsFolder);
            return(new IOpcNode[] { machineNode });
        }
Пример #10
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);
        }
Пример #11
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>());
        }
Пример #12
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 });
        }
        /// <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 });
        }
Пример #14
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 });
        }
Пример #15
0
 protected override IEnumerable <IOpcNode> CreateNodes(OpcNodeReferenceCollection references)
 {
     references.Add(this.rootNode, OpcObjectTypes.ObjectsFolder);
     return(new IOpcNode[] { this.rootNode });
 }
        /// <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 });
        }
Пример #17
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);
        }