/// <summary> /// Replaces the generic node with a node specific to the model. /// </summary> protected override NodeState AddBehaviourToPredefinedNode(ISystemContext context, NodeState predefinedNode) { BaseObjectState passiveNode = predefinedNode as BaseObjectState; if (passiveNode == null) { return(predefinedNode); } NodeId typeId = passiveNode.TypeDefinitionId; if (!IsNodeIdInNamespace(typeId) || typeId.IdType != IdType.Numeric) { return(predefinedNode); } switch ((uint)typeId.Identifier) { case ObjectTypes.BoilerType: { if (passiveNode is BoilerState) { break; } BoilerState activeNode = new BoilerState(passiveNode.Parent); activeNode.Create(context, passiveNode); // replace the node in the parent. if (passiveNode.Parent != null) { passiveNode.Parent.ReplaceChild(context, activeNode); } // Autostart boiler simulation state machine MethodState start = (MethodState)activeNode.Simulation.FindChild(context, Opc.Ua.BrowseNames.Start); if (start != null) { IList <Variant> inputArguments = new List <Variant>(); IList <Variant> outputArguments = new List <Variant>(); List <ServiceResult> errors = new List <ServiceResult>(); start.Call(context, activeNode.NodeId, inputArguments, errors, outputArguments); } return(activeNode); } } return(predefinedNode); }
/// <summary> /// Creates a boiler and adds it to the address space. /// </summary> /// <param name="context">The context to use.</param> /// <param name="unitNumber">The unit number for the boiler.</param> private void CreateBoiler(SystemContext context, int unitNumber) { BoilerState boiler = new BoilerState(null); string name = Utils.Format("Boiler #{0}", unitNumber); boiler.Create( context, null, new QualifiedName(name, m_namespaceIndex), null, true); NodeState folder = (NodeState)FindPredefinedNode( ExpandedNodeId.ToNodeId(ObjectIds.Boilers, Server.NamespaceUris), typeof(NodeState)); folder.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, false, boiler.NodeId); boiler.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, true, folder.NodeId); string unitLabel = Utils.Format("{0}0", unitNumber); UpdateDisplayName(boiler.InputPipe, unitLabel); UpdateDisplayName(boiler.Drum, unitLabel); UpdateDisplayName(boiler.OutputPipe, unitLabel); UpdateDisplayName(boiler.LevelController, unitLabel); UpdateDisplayName(boiler.FlowController, unitLabel); UpdateDisplayName(boiler.CustomController, unitLabel); m_boilers.Add(boiler); AddPredefinedNode(context, boiler); // Autostart boiler simulation state machine MethodState start = (MethodState)boiler.Simulation.FindChild(context, Opc.Ua.BrowseNames.Start); if (start != null) { IList <Variant> inputArguments = new List <Variant>(); IList <Variant> outputArguments = new List <Variant>(); List <ServiceResult> errors = new List <ServiceResult>(); start.Call(context, boiler.NodeId, inputArguments, errors, outputArguments); } }
/// <summary> /// Calls a method on an object. /// </summary> protected virtual ServiceResult Call( ISystemContext context, CallMethodRequest methodToCall, NodeState source, MethodState method, CallMethodResult result) { ServerSystemContext systemContext = context as ServerSystemContext; List<ServiceResult> argumentErrors = new List<ServiceResult>(); VariantCollection outputArguments = new VariantCollection(); ServiceResult error = method.Call( context, source.NodeId, methodToCall.InputArguments, argumentErrors, outputArguments); if (ServiceResult.IsBad(error)) { return error; } // check for argument errors. bool argumentsValid = true; for (int jj = 0; jj < argumentErrors.Count; jj++) { ServiceResult argumentError = argumentErrors[jj]; if (argumentError != null) { result.InputArgumentResults.Add(argumentError.StatusCode); if (ServiceResult.IsBad(argumentError)) { argumentsValid = false; } } else { result.InputArgumentResults.Add(StatusCodes.Good); } // only fill in diagnostic info if it is requested. if ((systemContext.OperationContext.DiagnosticsMask & DiagnosticsMasks.OperationAll) != 0) { if (ServiceResult.IsBad(argumentError)) { argumentsValid = false; result.InputArgumentDiagnosticInfos.Add(new DiagnosticInfo(argumentError, systemContext.OperationContext.DiagnosticsMask, false, systemContext.OperationContext.StringTable)); } else { result.InputArgumentDiagnosticInfos.Add(null); } } } // check for validation errors. if (!argumentsValid) { result.StatusCode = StatusCodes.BadInvalidArgument; return result.StatusCode; } // do not return diagnostics if there are no errors. result.InputArgumentDiagnosticInfos.Clear(); // return output arguments. result.OutputArguments = outputArguments; return ServiceResult.Good; }