private ServiceResult OnWriteAnalog( ISystemContext context, NodeState node, NumericRange indexRange, QualifiedName dataEncoding, ref object value, ref StatusCode statusCode, ref DateTime timestamp) { AnalogItemState variable = node as AnalogItemState; // verify data type. Opc.Ua.TypeInfo typeInfo = Opc.Ua.TypeInfo.IsInstanceOfDataType( value, variable.DataType, variable.ValueRank, context.NamespaceUris, context.TypeTable); if (typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown) { return(StatusCodes.BadTypeMismatch); } // check index range. if (variable.ValueRank >= 0) { if (indexRange != NumericRange.Empty) { object target = variable.Value; ServiceResult result = indexRange.UpdateRange(ref target, value); if (ServiceResult.IsBad(result)) { return(result); } value = target; } } // check instrument range. else { if (indexRange != NumericRange.Empty) { return(StatusCodes.BadIndexRangeInvalid); } double number = Convert.ToDouble(value); if (variable.InstrumentRange != null && (number < variable.InstrumentRange.Value.Low || number > variable.InstrumentRange.Value.High)) { return(StatusCodes.BadOutOfRange); } } return(ServiceResult.Good); }
/// <summary> /// Updates the measurement and calculates the new control output. /// </summary> public double UpdateMeasurement(AnalogItemState <double> source) { Range range = source.EURange.Value; m_measurement.Value = source.Value; // clamp the set-point. if (range != null) { if (m_setPoint.Value > range.High) { m_setPoint.Value = range.High; } if (m_setPoint.Value < range.Low) { m_setPoint.Value = range.Low; } } // calculate error. m_controlOut.Value = m_setPoint.Value - m_measurement.Value; if (range != null) { m_controlOut.Value /= range.Magnitude(); if (Math.Abs(m_controlOut.Value) > 1.0) { m_controlOut.Value = (m_controlOut.Value < 0) ? -1.0 : +1.0; } } // return the new output. return(m_controlOut.Value); }
/// <summary> /// Updates the measurement and calculates the new control output. /// </summary> public double UpdateMeasurement(AnalogItemState<double> source) { Range range = source.EURange.Value; m_measurement.Value = source.Value; // clamp the setpoint. if (range != null) { if (m_setPoint.Value > range.High) { m_setPoint.Value = range.High; } if (m_setPoint.Value < range.Low) { m_setPoint.Value = range.Low; } } // calculate error. m_controlOut.Value = m_setPoint.Value - m_measurement.Value; if (range != null) { m_controlOut.Value /= range.Magnitude; if (Math.Abs(m_controlOut.Value) > 1.0) { m_controlOut.Value = (m_controlOut.Value < 0)?-1.0:+1.0; } } // return the new output. return m_controlOut.Value; }
/// <summary> /// Returns the value as a percentage of the range. /// </summary> private double GetPercentage(AnalogItemState <double> value) { double percentage = value.Value; Range range = value.EURange.Value; if (range != null) { percentage /= Math.Abs(range.High - range.Low); if (Math.Abs(percentage) > 1.0) { percentage = 1.0; } } return(percentage); }
private ServiceResult OnWriteAnalogRange( ISystemContext context, NodeState node, NumericRange indexRange, QualifiedName dataEncoding, ref object value, ref StatusCode statusCode, ref DateTime timestamp) { PropertyState <Opc.Ua.Range> variable = node as PropertyState <Opc.Ua.Range>; ExtensionObject extensionObject = value as ExtensionObject; TypeInfo typeInfo = TypeInfo.Construct(value); if (variable == null || extensionObject == null || typeInfo == null || typeInfo == Opc.Ua.TypeInfo.Unknown) { return(StatusCodes.BadTypeMismatch); } Opc.Ua.Range newRange = extensionObject.Body as Opc.Ua.Range; AnalogItemState parent = variable.Parent as AnalogItemState; if (newRange == null || parent == null) { return(StatusCodes.BadTypeMismatch); } if (indexRange != NumericRange.Empty) { return(StatusCodes.BadIndexRangeInvalid); } TypeInfo parentTypeInfo = TypeInfo.Construct(parent.Value); Opc.Ua.Range parentRange = GetAnalogRange(parentTypeInfo.BuiltInType); if (parentRange.High < newRange.High || parentRange.Low > newRange.Low) { return(StatusCodes.BadOutOfRange); } value = newRange; return(ServiceResult.Good); }
public void ConstructorTest() { AnalogItemState <double> _item = new AnalogItemState <double>(null, "browseName", ModelExtensions.CreateRange(0, 1), 0.5); Assert.AreEqual <string>("browseName", _item.BrowseName.Name); Assert.IsFalse(_item.BrowseName.NamespaceIndexSpecified); //EURange Assert.IsNotNull(_item.EURange); Assert.AreEqual <string>(nameof(_item.EURange), _item.EURange.BrowseName.Name); Assert.AreEqual <double>(1, _item.EURange.Value.High); Assert.AreEqual <double>(0, _item.EURange.Value.Low); //Value Assert.IsNotNull(_item.Value); Assert.AreEqual <double>(0.5, _item.Value); Assert.AreEqual <NodeClass>(NodeClass.Variable_2, _item.NodeClass); Assert.IsNull(_item.Parent); Assert.AreEqual <double>(0.5, _item.Value); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case TutorialModel.BrowseNames.Input: { if (createOrReplace) { if (Input == null) { if (replacement == null) { Input = new AnalogItemState <double>(this); } else { Input = (AnalogItemState <double>)replacement; } } } instance = Input; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case ITSOPCCourseCode.OPCUA.SampleServer.BrowseNames.CurrentSpeed: { if (createOrReplace) { if (CurrentSpeed == null) { if (replacement == null) { CurrentSpeed = new AnalogItemState <double>(this); } else { CurrentSpeed = (AnalogItemState <double>)replacement; } } } instance = CurrentSpeed; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Called each time the scan cycle completes. /// </summary> private void DoScan(object state) { try { // must acquire the lock. lock (m_activeItems) { for (int ii = 0; ii < m_activeItems.Count; ii++) { NodeHandle handle = m_activeItems[ii].ManagerHandle as NodeHandle; // simulate a value change and read from an external source. double value = 0; if (!m_externalValues.TryGetValue(handle.RootId, out value)) { m_externalValues.Add(handle.RootId, value); } value++; m_externalValues[handle.RootId] = value; // use the in memory object as a cache. AnalogItemState <double> item = handle.Node as AnalogItemState <double>; item.Value = value; // push data change. m_activeItems[ii].QueueValue(new DataValue(new Variant(value), StatusCodes.Good, DateTime.UtcNow, DateTime.UtcNow), null); } } } catch (Exception e) { Utils.Trace(e, "Unexpected error doing scan."); } }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case Quickstarts.Engineering.BrowseNames.SerialNumber: { if (createOrReplace) { if (SerialNumber == null) { if (replacement == null) { SerialNumber = new PropertyState<string>(this); } else { SerialNumber = (PropertyState<string>)replacement; } } } instance = SerialNumber; break; } case Quickstarts.Engineering.BrowseNames.Manufacturer: { if (createOrReplace) { if (Manufacturer == null) { if (replacement == null) { Manufacturer = new PropertyState<string>(this); } else { Manufacturer = (PropertyState<string>)replacement; } } } instance = Manufacturer; break; } case Quickstarts.Operations.BrowseNames.SetPoint: { if (createOrReplace) { if (SetPoint == null) { if (replacement == null) { SetPoint = new AnalogItemState<double>(this); } else { SetPoint = (AnalogItemState<double>)replacement; } } } instance = SetPoint; break; } case Quickstarts.Operations.BrowseNames.Measurement: { if (createOrReplace) { if (Measurement == null) { if (replacement == null) { Measurement = new AnalogItemState<double>(this); } else { Measurement = (AnalogItemState<double>)replacement; } } } instance = Measurement; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case Quickstarts.HistoricalEvents.BrowseNames.TestDuration: { if (createOrReplace) { if (TestDuration == null) { if (replacement == null) { TestDuration = new AnalogItemState<double>(this); } else { TestDuration = (AnalogItemState<double>)replacement; } } } instance = TestDuration; break; } case Quickstarts.HistoricalEvents.BrowseNames.InjectedFluid: { if (createOrReplace) { if (InjectedFluid == null) { if (replacement == null) { InjectedFluid = new PropertyState<string>(this); } else { InjectedFluid = (PropertyState<string>)replacement; } } } instance = InjectedFluid; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case TutorialModel.BrowseNames.Input: { if (createOrReplace) { if (Input == null) { if (replacement == null) { Input = new AnalogItemState<double>(this); } else { Input = (AnalogItemState<double>)replacement; } } } instance = Input; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
private AnalogItemState CreateAnalogItemVariable(NodeState parent, string path, string name, NodeId dataType) { int valueRank = ValueRanks.Scalar; var variable = new AnalogItemState(parent); variable.BrowseName = new QualifiedName(path, NamespaceIndex); variable.EngineeringUnits = new PropertyState <EUInformation>(variable); variable.InstrumentRange = new PropertyState <Opc.Ua.Range>(variable); variable.Create( SystemContext, new NodeId(path, NamespaceIndex), variable.BrowseName, null, true); variable.NodeId = new NodeId(path, NamespaceIndex); variable.SymbolicName = name; variable.DisplayName = name; variable.WriteMask = AttributeWriteMask.None; variable.UserWriteMask = AttributeWriteMask.None; variable.ReferenceTypeId = ReferenceTypes.Organizes; variable.DataType = dataType; variable.ValueRank = valueRank; variable.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variable.Historizing = false; variable.OnReadUserRolePermissions = OnReadUserRolePermissions; if (valueRank == ValueRanks.OneDimension) { variable.ArrayDimensions = new ReadOnlyList <uint>(new List <uint> { 0 }); } else if (valueRank == ValueRanks.TwoDimensions) { variable.ArrayDimensions = new ReadOnlyList <uint>(new List <uint> { 0, 0 }); } BuiltInType builtInType = Opc.Ua.TypeInfo.GetBuiltInType(dataType, Server.TypeTree); // Using anything but 120,-10 fails a few tests variable.InstrumentRange.Value = GetAnalogRange(builtInType);; variable.EURange.Value = new Opc.Ua.Range(100, 0); variable.Value = Opc.Ua.TypeInfo.GetDefaultValue(dataType, valueRank, Server.TypeTree); variable.StatusCode = StatusCodes.Good; variable.Timestamp = DateTime.UtcNow; // The latest UNECE version (Rev 11, published in 2015) is available here: // http://www.opcfoundation.org/UA/EngineeringUnits/UNECE/rec20_latest_08052015.zip variable.EngineeringUnits.Value = new EUInformation("mV", "millivolt", "http://www.opcfoundation.org/UA/units/un/cefact"); // The mapping of the UNECE codes to OPC UA(EUInformation.unitId) is available here: // http://www.opcfoundation.org/UA/EngineeringUnits/UNECE/UNECE_to_OPCUA.csv variable.EngineeringUnits.Value.UnitId = 12890; // "2Z" variable.OnWriteValue = OnWriteAnalog; variable.EURange.OnWriteValue = OnWriteAnalogRange; variable.EURange.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.EURange.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variable.EngineeringUnits.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.EngineeringUnits.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variable.InstrumentRange.OnWriteValue = OnWriteAnalogRange; variable.InstrumentRange.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.InstrumentRange.UserAccessLevel = AccessLevels.CurrentReadOrWrite; if (parent != null) { parent.AddChild(variable); } return(variable); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case ObjectTypeTest.BrowseNames.BrowseName4node66: { if (createOrReplace) { if (BrowseName4node66 == null) { if (replacement == null) { BrowseName4node66 = new PropertyState <LocalizedText>(this); } else { BrowseName4node66 = (PropertyState <LocalizedText>)replacement; } } } instance = BrowseName4node66; break; } case ObjectTypeTest.BrowseNames.NameNotSet1109: { if (createOrReplace) { if (NameNotSet1109 == null) { if (replacement == null) { NameNotSet1109 = new AnalogItemState(this); } else { NameNotSet1109 = (AnalogItemState)replacement; } } } instance = NameNotSet1109; break; } case ObjectTypeTest.BrowseNames.ChildMethod: { if (createOrReplace) { if (ChildMethod == null) { if (replacement == null) { ChildMethod = new ChildMethodComplexObjectMethodState(this); } else { ChildMethod = (ChildMethodComplexObjectMethodState)replacement; } } } instance = ChildMethod; break; } case ObjectTypeTest.BrowseNames.NonExecutableMethod: { if (createOrReplace) { if (NonExecutableMethod == null) { if (replacement == null) { NonExecutableMethod = new MethodState(this); } else { NonExecutableMethod = (MethodState)replacement; } } } instance = NonExecutableMethod; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Validates an emphermal node. /// </summary> private NodeState ValidateExternalNode(ISystemContext context, NodeHandle handle) { string uniqueId = handle.RootId.Identifier as string; if (String.IsNullOrEmpty(uniqueId)) { return(null); } // lookup in persistent cache (nodes that are being monitored are in the cache). NodeState target = LookupNodeInComponentCache(context, handle); if (target != null) { return(target); } // validate the external node (normally this means look it up in underlying system). switch (uniqueId) { case "Alpha": case "Omega": { // create the variable. AnalogItemState <double> target2 = new AnalogItemState <double>(null); // instantiate based on the type model. assigns ids automatically using SystemContext.NodeIdFactory target2.Create( SystemContext, handle.RootId, new QualifiedName(uniqueId, NamespaceIndex), null, true); // always allow read/write. target2.AccessLevel = AccessLevels.CurrentReadOrWrite; target2.UserAccessLevel = AccessLevels.CurrentReadOrWrite; target2.StatusCode = StatusCodes.BadWaitingForInitialData; #region Task #D4 - Add Support for Access Control target2.OnReadUserAccessLevel = OnReadUserAccessLevel; #endregion target = target2; break; } default: { return(null); } } // validate component. if (!String.IsNullOrEmpty(handle.ComponentPath)) { NodeState component = target.FindChildBySymbolicName(context, handle.ComponentPath); // component does not exist. if (component == null) { return(null); } target = component; } return(target); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case HistoricalEvents.BrowseNames.FluidLevel: { if (createOrReplace) { if (FluidLevel == null) { if (replacement == null) { FluidLevel = new AnalogItemState <double>(this); } else { FluidLevel = (AnalogItemState <double>)replacement; } } } instance = FluidLevel; break; } case HistoricalEvents.BrowseNames.TestedBy: { if (createOrReplace) { if (TestedBy == null) { if (replacement == null) { TestedBy = new PropertyState <string>(this); } else { TestedBy = (PropertyState <string>)replacement; } } } instance = TestedBy; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case FileSystem.BrowseNames.Temperature: { if (createOrReplace) { if (Temperature == null) { if (replacement == null) { Temperature = new AnalogItemState<double>(this); } else { Temperature = (AnalogItemState<double>)replacement; } } } instance = Temperature; break; } case FileSystem.BrowseNames.TemperatureSetPoint: { if (createOrReplace) { if (TemperatureSetPoint == null) { if (replacement == null) { TemperatureSetPoint = new AnalogItemState<double>(this); } else { TemperatureSetPoint = (AnalogItemState<double>)replacement; } } } instance = TemperatureSetPoint; break; } case FileSystem.BrowseNames.State: { if (createOrReplace) { if (State == null) { if (replacement == null) { State = new BaseDataVariableState<int>(this); } else { State = (BaseDataVariableState<int>)replacement; } } } instance = State; break; } case FileSystem.BrowseNames.PowerConsumption: { if (createOrReplace) { if (PowerConsumption == null) { if (replacement == null) { PowerConsumption = new DataItemState<double>(this); } else { PowerConsumption = (DataItemState<double>)replacement; } } } instance = PowerConsumption; break; } case FileSystem.BrowseNames.Start: { if (createOrReplace) { if (Start == null) { if (replacement == null) { Start = new MethodState(this); } else { Start = (MethodState)replacement; } } } instance = Start; break; } case FileSystem.BrowseNames.Stop: { if (createOrReplace) { if (Stop == null) { if (replacement == null) { Stop = new MethodState(this); } else { Stop = (MethodState)replacement; } } } instance = Stop; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case ObjectTypeTest.BrowseNames.BrowseName4node66: { if (createOrReplace) { if (BrowseName4node66 == null) { if (replacement == null) { BrowseName4node66 = new PropertyState<LocalizedText>(this); } else { BrowseName4node66 = (PropertyState<LocalizedText>)replacement; } } } instance = BrowseName4node66; break; } case ObjectTypeTest.BrowseNames.NameNotSet1109: { if (createOrReplace) { if (NameNotSet1109 == null) { if (replacement == null) { NameNotSet1109 = new AnalogItemState(this); } else { NameNotSet1109 = (AnalogItemState)replacement; } } } instance = NameNotSet1109; break; } case ObjectTypeTest.BrowseNames.ChildMethod: { if (createOrReplace) { if (ChildMethod == null) { if (replacement == null) { ChildMethod = new ChildMethodComplexObjectMethodState(this); } else { ChildMethod = (ChildMethodComplexObjectMethodState)replacement; } } } instance = ChildMethod; break; } case ObjectTypeTest.BrowseNames.NonExecutableMethod: { if (createOrReplace) { if (NonExecutableMethod == null) { if (replacement == null) { NonExecutableMethod = new MethodState(this); } else { NonExecutableMethod = (MethodState)replacement; } } } instance = NonExecutableMethod; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Creates a variable from a tag. /// </summary> /// <param name="context">The context.</param> /// <param name="tag">The tag.</param> /// <returns>The variable that represents the tag.</returns> private BaseVariableState CreateVariable(ISystemContext context, UnderlyingSystemTag tag) { // create the variable type based on the tag type. BaseDataVariableState variable = null; switch (tag.TagType) { case UnderlyingSystemTagType.Analog: { AnalogItemState node = new AnalogItemState(this); if (tag.EngineeringUnits != null) { node.EngineeringUnits = new PropertyState <EUInformation>(node); } if (tag.EuRange.Length >= 4) { node.InstrumentRange = new PropertyState <Range>(node); } variable = node; break; } case UnderlyingSystemTagType.Digital: { TwoStateDiscreteState node = new TwoStateDiscreteState(this); variable = node; break; } case UnderlyingSystemTagType.Enumerated: { MultiStateDiscreteState node = new MultiStateDiscreteState(this); if (tag.Labels != null) { node.EnumStrings = new PropertyState <LocalizedText[]>(node); } variable = node; break; } default: { DataItemState node = new DataItemState(this); variable = node; break; } } // set the symbolic name and reference types. variable.SymbolicName = tag.Name; variable.ReferenceTypeId = ReferenceTypeIds.HasComponent; // initialize the variable from the type model. variable.Create( context, null, new QualifiedName(tag.Name, this.BrowseName.NamespaceIndex), null, true); // update the variable values. UpdateVariable(context, tag, variable); return(variable); }
/// <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) { //Load DI nodeset LoadPredefinedNodes(SystemContext, externalReferences); //Add my variables to Address Space, under the DeviceSet object ----------------------- //------------------------------------------------------------------------------------- //get the DeviceSet object of the Address Space NodeState DeviceSetobj = (NodeState)FindPredefinedNode( ExpandedNodeId.ToNodeId(ObjectIds.DeviceSet, Server.NamespaceUris), typeof(NodeState)); //------------------------------------------------------------------------------------- //create myDevice1 as a simple folder with a variable FolderState mydev1 = CreateFolder(DeviceSetobj, "myDevice1", "myDevice1"); //create myDevice1/myVar1 BaseDataVariableState myvar1 = CreateVariable(mydev1, "myVar1", "myVar1", Opc.Ua.DataTypeIds.Double, ValueRanks.Scalar); //create myDevice1/Actual_State BaseDataVariableState Actual_State = CreateVariable(mydev1, "Actual_State", "Actual_State", Opc.Ua.DataTypeIds.Double, ValueRanks.Scalar); //create myDevice1/Sensors_Data Sensors_Data = CreateVariable(mydev1, "Sensors_Data", "Sensors_Data", Opc.Ua.DataTypeIds.Double, ValueRanks.OneDimension); //create myDevice1/myVar2 myvar2 = CreateVariable(mydev1, "myVar2", "myVar2", Opc.Ua.DataTypeIds.Int16, ValueRanks.Scalar); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Poject //create myDevice1/Start_Piece Start_Piece = CreateVariable(mydev1, "Start_Piece", "Start_Piece", Opc.Ua.DataTypeIds.Boolean, ValueRanks.Scalar); // create myDevice1/Mould_1 Mould_1 = CreateVariable(mydev1, "Mould_1", "Mould_1", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); // create myDevice1/Mould_1_SN Mould_1_SN = CreateVariable(mydev1, "Mould_1_SN", "Mould_1_SN", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); // create myDevice1/Mould_2 Mould_2 = CreateVariable(mydev1, "Mould_2", "Mould_2", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); // create myDevice1/Mould_2_SN Mould_2_SN = CreateVariable(mydev1, "Mould_2_SN", "Mould_2_SN", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); // create myDevice1/Piece_SN Piece_SN = CreateVariable(mydev1, "Piece_SN", "Piece_SN", Opc.Ua.DataTypeIds.Int32, ValueRanks.Scalar); // create myDevice1/Piece_SN Machine_SN = CreateVariable(mydev1, "Machine_SN", "Machine_SN", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); //create myDevice1/Change_Mould Change_Mould = CreateVariable(mydev1, "Change_Mould", "Change_Mould", Opc.Ua.DataTypeIds.Boolean, ValueRanks.Scalar); //create myDevice1/Mould_Changed Mould_Changed = CreateVariable(mydev1, "Mould_Changed", "Mould_Changed", Opc.Ua.DataTypeIds.Boolean, ValueRanks.Scalar); // create myDevice1/Actual_Mould Actual_Mould = CreateVariable(mydev1, "Actual_Mould", "Actual_Mould", Opc.Ua.DataTypeIds.Int32, ValueRanks.Scalar); // create myDevice1/Mould_tobeused Mould_tobeused = CreateVariable(mydev1, "Mould_tobeused", "Mould_tobeused", Opc.Ua.DataTypeIds.String, ValueRanks.Scalar); // create myDevice1/Operator_ID Operator_ID = CreateVariable(mydev1, "Operator_ID", "Operator_ID", Opc.Ua.DataTypeIds.Int32, ValueRanks.Scalar); // create myDevice1/Robot_Finished Robot_Finished = CreateVariable(mydev1, "Robot_Finished", "Robot_Finished", Opc.Ua.DataTypeIds.Boolean, ValueRanks.Scalar); //initialize var myvar1.Value = (double)0.0; myvar2.Value = (short)0; Actual_State.Value = (double)0.0; Start_Piece.Value = (bool)false; Mould_1.Value = (string)"Mould 1"; Mould_2.Value = (string)"Mould 2"; Mould_1_SN.Value = (string)"1"; Mould_2_SN.Value = (string)"2"; Piece_SN.Value = (int)1; Machine_SN.Value = (string)"1"; Change_Mould.Value = (bool)false; Robot_Finished.Value = (bool)true; Actual_Mould.Value = (int)0; //Sensors_Data.Value = (int[])null; Mould_tobeused.Value = Mould_1_SN.Value; Mould_Changed.Value = (bool)false; //store variable in my variable list for latter access (not necessary if variable is declare as a field of the class) m_dynamicNodes.Add(myvar1); m_dynamicNodes.Add(Actual_State); //add to Address Space AddPredefinedNode(SystemContext, mydev1); //------------------------------------------------------------------------------------- //Create a new object using the type "Device" defined by the DI specification //The class DeviceState is defined in the code generated by ModelCompiler myTemperatureSensor = new DeviceState(null); myTemperatureSensor.Create(SystemContext, null, new QualifiedName("myTemperatureSensor", m_namespaceIndex), null, true); //Object is created under DeviceSet DeviceSetobj.AddChild(myTemperatureSensor); //create a variable to hold the value of the temperature, of the type AnalogItem, under myTemperatureSensor TemperatureValue = new AnalogItemState(null); TemperatureValue.Create(SystemContext, null, new QualifiedName("Temperature", m_namespaceIndex), null, true); //Object is created under myTemperatureSensor myTemperatureSensor.AddChild(TemperatureValue); //initialize var TemperatureValue.Value = (double)0.0; //the type "Device" has a set of predefined info variables myTemperatureSensor.SerialNumber.Value = "AABB112233"; myTemperatureSensor.Manufacturer.Value = "ACME"; myTemperatureSensor.Model.Value = new LocalizedText("PT", "MODEL 1.0"); //add to Address Space AddPredefinedNode(SystemContext, myTemperatureSensor); //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- //initialize Modbus client Modbus_client = new ModbusClient(Modbus_IP, Modbus_port); Modbus_client.ConnectionTimeout = 5000; // start periodic method to update my Address Space variables m_doprocessingTimer = new Timer(myDoProcessing, null, m_doprocessingInterval, m_doprocessingInterval); } }
/// <summary> /// Validates an emphermal node. /// </summary> private NodeState ValidateExternalNode(ISystemContext context, NodeHandle handle) { string uniqueId = handle.RootId.Identifier as string; if (String.IsNullOrEmpty(uniqueId)) { return null; } // lookup in persistent cache (nodes that are being monitored are in the cache). NodeState target = LookupNodeInComponentCache(context, handle); if (target != null) { return target; } // validate the external node (normally this means look it up in underlying system). switch (uniqueId) { case "Alpha": case "Omega": { // create the variable. AnalogItemState<double> target2 = new AnalogItemState<double>(null); // instantiate based on the type model. assigns ids automatically using SystemContext.NodeIdFactory target2.Create( SystemContext, handle.RootId, new QualifiedName(uniqueId, NamespaceIndex), null, true); // always allow read/write. target2.AccessLevel = AccessLevels.CurrentReadOrWrite; target2.UserAccessLevel = AccessLevels.CurrentReadOrWrite; target2.StatusCode = StatusCodes.BadWaitingForInitialData; #region Task #D4 - Add Support for Access Control target2.OnReadUserAccessLevel = OnReadUserAccessLevel; #endregion target = target2; break; } default: { return null; } } // validate component. if (!String.IsNullOrEmpty(handle.ComponentPath)) { NodeState component = target.FindChildBySymbolicName(context, handle.ComponentPath); // component does not exist. if (component == null) { return null; } target = component; } return target; }
/// <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); #region Task #A1 - Create Root Folder // create the root folder. FolderState root = new FolderState(null); root.NodeId = GenerateNodeId(); root.BrowseName = new QualifiedName("Root", NamespaceIndex); root.DisplayName = root.BrowseName.Name; root.TypeDefinitionId = ObjectTypeIds.FolderType; // ensure root can be found via the server object. IList<IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List<IReference>(); } root.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, root.NodeId)); // save the node for later lookup. AddPredefinedNode(SystemContext, root); #endregion #region Task #A2 - Create Object Instance with a Property // create the folder object. BaseObjectState instance = new BaseObjectState(null); instance.NodeId = GenerateNodeId(); instance.BrowseName = new QualifiedName("Object", NamespaceIndex); instance.DisplayName = instance.BrowseName.Name; instance.TypeDefinitionId = ObjectTypeIds.BaseObjectType; // create a losely coupled relationship with the root object. root.AddReference(ReferenceTypeIds.Organizes, false, instance.NodeId); instance.AddReference(ReferenceTypeIds.Organizes, true, root.NodeId); // create a property. PropertyState<int> property = new PropertyState<int>(instance); property.NodeId = GenerateNodeId(); property.BrowseName = new QualifiedName("Property", NamespaceIndex); property.DisplayName = property.BrowseName.Name; property.TypeDefinitionId = VariableTypeIds.PropertyType; property.DataType = DataTypeIds.Int32; property.ValueRank = ValueRanks.Scalar; property.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; property.AccessLevel = AccessLevels.CurrentReadOrWrite; property.UserAccessLevel = AccessLevels.CurrentReadOrWrite; property.Historizing = false; property.ReferenceTypeId = ReferenceTypeIds.HasProperty; // create a property that is tightly coupled. instance.AddChild(property); // save the node for later lookup (all tightly coupled children are added with this call). AddPredefinedNode(SystemContext, instance); #endregion #region Task #A3 - Create a Variable using the Built-in Type Model // create the variable. AnalogItemState<double> variable = new AnalogItemState<double>(instance); // add optional properties. variable.InstrumentRange = new PropertyState<Range>(variable); // instantiate based on the type model. assigns ids automatically using SystemContext.NodeIdFactory variable.Create( SystemContext, GenerateNodeId(), new QualifiedName("Variable", NamespaceIndex), null, true); // set default values. variable.EURange.Value = new Range(90, 10); variable.InstrumentRange.Value = new Range(100, 0); // tightly coupled. instance.AddChild(variable); // need to add it manually since its parent was already added. AddPredefinedNode(SystemContext, variable); #endregion #region Task #A4 - Add Dynamic Behavoir by Updating In-Memory Nodes m_property = property; m_simulationTimer = new Timer(DoSimulation, null, 1000, 1000); #endregion #region Task #A5 - Add Support for External Nodes // External nodes are nodes that reference an entity which stored elsewhere. // These nodes use no memory in the server unless they are accessed. // The NodeId is a string that is used to create the external node on demand. root.AddReference(ReferenceTypeIds.Organizes, false, CreateNodeId("Alpha")); root.AddReference(ReferenceTypeIds.Organizes, false, CreateNodeId("Omega")); #endregion #region Task #A7 - Add Support for Method MethodState method = new MethodState(instance); method.NodeId = GenerateNodeId(); method.BrowseName = new QualifiedName("Method", NamespaceIndex); method.DisplayName = method.BrowseName.Name; method.Executable = true; method.UserExecutable = true; method.ReferenceTypeId = ReferenceTypeIds.HasComponent; instance.AddChild(method); // create the input arguments. PropertyState<Argument[]> inputArguments = new PropertyState<Argument[]>(method); inputArguments.NodeId = GenerateNodeId(); inputArguments.BrowseName = new QualifiedName(BrowseNames.InputArguments); inputArguments.DisplayName = inputArguments.BrowseName.Name; inputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; inputArguments.DataType = DataTypeIds.Argument; inputArguments.ValueRank = ValueRanks.OneDimension; inputArguments.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; inputArguments.AccessLevel = AccessLevels.CurrentRead; inputArguments.UserAccessLevel = AccessLevels.CurrentRead; inputArguments.Historizing = false; inputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; inputArguments.Value = new Argument[] { new Argument() { Name = "CurrentCount", Description = "The current count.", DataType = DataTypeIds.Int32, ValueRank = ValueRanks.Scalar } }; method.InputArguments = inputArguments; // create the output arguments. PropertyState<Argument[]> outputArguments = new PropertyState<Argument[]>(method); outputArguments.NodeId = GenerateNodeId(); outputArguments.BrowseName = new QualifiedName(BrowseNames.OutputArguments); outputArguments.DisplayName = outputArguments.BrowseName.Name; outputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; outputArguments.DataType = DataTypeIds.Argument; outputArguments.ValueRank = ValueRanks.OneDimension; outputArguments.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; outputArguments.AccessLevel = AccessLevels.CurrentRead; outputArguments.UserAccessLevel = AccessLevels.CurrentRead; outputArguments.Historizing = false; outputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; outputArguments.Value = new Argument[] { new Argument() { Name = "NewCount", Description = "The new count.", DataType = DataTypeIds.Int32, ValueRank = ValueRanks.Scalar } }; method.OutputArguments = outputArguments; // save the node for later lookup (all tightly coupled children are added with this call). AddPredefinedNode(SystemContext, instance); // register handler. method.OnCallMethod = new GenericMethodCalledEventHandler(DoMethodCall); #endregion #region Task #D6 - Add Support for Notifiers // enable subscriptions. root.EventNotifier = EventNotifiers.SubscribeToEvents; // creating notifier ensures events propogate up the hierarchy when the are produced. AddRootNotifier(root); // add link to server object. if (!externalReferences.TryGetValue(ObjectIds.Server, out references)) { externalReferences[ObjectIds.Server] = references = new List<IReference>(); } references.Add(new NodeStateReference(ReferenceTypeIds.HasNotifier, false, root.NodeId)); // add sub-notifiers. instance.EventNotifier = EventNotifiers.SubscribeToEvents; instance.AddNotifier(SystemContext, ReferenceTypeIds.HasNotifier, true, root); root.AddNotifier(SystemContext, ReferenceTypeIds.HasNotifier, false, instance); #endregion } }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case TestData.BrowseNames.SByteValue: { if (createOrReplace) { if (SByteValue == null) { if (replacement == null) { SByteValue = new AnalogItemState<sbyte>(this); } else { SByteValue = (AnalogItemState<sbyte>)replacement; } } } instance = SByteValue; break; } case TestData.BrowseNames.ByteValue: { if (createOrReplace) { if (ByteValue == null) { if (replacement == null) { ByteValue = new AnalogItemState<byte>(this); } else { ByteValue = (AnalogItemState<byte>)replacement; } } } instance = ByteValue; break; } case TestData.BrowseNames.Int16Value: { if (createOrReplace) { if (Int16Value == null) { if (replacement == null) { Int16Value = new AnalogItemState<short>(this); } else { Int16Value = (AnalogItemState<short>)replacement; } } } instance = Int16Value; break; } case TestData.BrowseNames.UInt16Value: { if (createOrReplace) { if (UInt16Value == null) { if (replacement == null) { UInt16Value = new AnalogItemState<ushort>(this); } else { UInt16Value = (AnalogItemState<ushort>)replacement; } } } instance = UInt16Value; break; } case TestData.BrowseNames.Int32Value: { if (createOrReplace) { if (Int32Value == null) { if (replacement == null) { Int32Value = new AnalogItemState<int>(this); } else { Int32Value = (AnalogItemState<int>)replacement; } } } instance = Int32Value; break; } case TestData.BrowseNames.UInt32Value: { if (createOrReplace) { if (UInt32Value == null) { if (replacement == null) { UInt32Value = new AnalogItemState<uint>(this); } else { UInt32Value = (AnalogItemState<uint>)replacement; } } } instance = UInt32Value; break; } case TestData.BrowseNames.Int64Value: { if (createOrReplace) { if (Int64Value == null) { if (replacement == null) { Int64Value = new AnalogItemState<long>(this); } else { Int64Value = (AnalogItemState<long>)replacement; } } } instance = Int64Value; break; } case TestData.BrowseNames.UInt64Value: { if (createOrReplace) { if (UInt64Value == null) { if (replacement == null) { UInt64Value = new AnalogItemState<ulong>(this); } else { UInt64Value = (AnalogItemState<ulong>)replacement; } } } instance = UInt64Value; break; } case TestData.BrowseNames.FloatValue: { if (createOrReplace) { if (FloatValue == null) { if (replacement == null) { FloatValue = new AnalogItemState<float>(this); } else { FloatValue = (AnalogItemState<float>)replacement; } } } instance = FloatValue; break; } case TestData.BrowseNames.DoubleValue: { if (createOrReplace) { if (DoubleValue == null) { if (replacement == null) { DoubleValue = new AnalogItemState<double>(this); } else { DoubleValue = (AnalogItemState<double>)replacement; } } } instance = DoubleValue; break; } case TestData.BrowseNames.NumberValue: { if (createOrReplace) { if (NumberValue == null) { if (replacement == null) { NumberValue = new AnalogItemState(this); } else { NumberValue = (AnalogItemState)replacement; } } } instance = NumberValue; break; } case TestData.BrowseNames.IntegerValue: { if (createOrReplace) { if (IntegerValue == null) { if (replacement == null) { IntegerValue = new AnalogItemState(this); } else { IntegerValue = (AnalogItemState)replacement; } } } instance = IntegerValue; break; } case TestData.BrowseNames.UIntegerValue: { if (createOrReplace) { if (UIntegerValue == null) { if (replacement == null) { UIntegerValue = new AnalogItemState(this); } else { UIntegerValue = (AnalogItemState)replacement; } } } instance = UIntegerValue; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case Engineering.BrowseNames.SerialNumber: { if (createOrReplace) { if (SerialNumber == null) { if (replacement == null) { SerialNumber = new PropertyState <string>(this); } else { SerialNumber = (PropertyState <string>)replacement; } } } instance = SerialNumber; break; } case Engineering.BrowseNames.Manufacturer: { if (createOrReplace) { if (Manufacturer == null) { if (replacement == null) { Manufacturer = new PropertyState <string>(this); } else { Manufacturer = (PropertyState <string>)replacement; } } } instance = Manufacturer; break; } case Operations.BrowseNames.SetPoint: { if (createOrReplace) { if (SetPoint == null) { if (replacement == null) { SetPoint = new AnalogItemState <double>(this); } else { SetPoint = (AnalogItemState <double>)replacement; } } } instance = SetPoint; break; } case Operations.BrowseNames.Measurement: { if (createOrReplace) { if (Measurement == null) { if (replacement == null) { Measurement = new AnalogItemState <double>(this); } else { Measurement = (AnalogItemState <double>)replacement; } } } instance = Measurement; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case DsatsDemo.BrowseNames.RPM: { if (createOrReplace) { if (RPM == null) { if (replacement == null) { RPM = new AnalogItemState<float>(this); } else { RPM = (AnalogItemState<float>)replacement; } } } instance = RPM; break; } case DsatsDemo.BrowseNames.Torque: { if (createOrReplace) { if (Torque == null) { if (replacement == null) { Torque = new AnalogItemState<float>(this); } else { Torque = (AnalogItemState<float>)replacement; } } } instance = Torque; break; } case DsatsDemo.BrowseNames.Amperes: { if (createOrReplace) { if (Amperes == null) { if (replacement == null) { Amperes = new AnalogItemState<float>(this); } else { Amperes = (AnalogItemState<float>)replacement; } } } instance = Amperes; break; } case DsatsDemo.BrowseNames.BrakeStatus: { if (createOrReplace) { if (BrakeStatus == null) { if (replacement == null) { BrakeStatus = new TwoStateDiscreteState(this); } else { BrakeStatus = (TwoStateDiscreteState)replacement; } } } instance = BrakeStatus; break; } case DsatsDemo.BrowseNames.Orientation: { if (createOrReplace) { if (Orientation == null) { if (replacement == null) { Orientation = new AnalogItemState<float>(this); } else { Orientation = (AnalogItemState<float>)replacement; } } } instance = Orientation; break; } case DsatsDemo.BrowseNames.IsRotatingClockwise: { if (createOrReplace) { if (IsRotatingClockwise == null) { if (replacement == null) { IsRotatingClockwise = new TwoStateDiscreteState(this); } else { IsRotatingClockwise = (TwoStateDiscreteState)replacement; } } } instance = IsRotatingClockwise; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <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); #region Task #A1 - Create Root Folder // create the root folder. FolderState root = new FolderState(null); root.NodeId = GenerateNodeId(); root.BrowseName = new QualifiedName("Root", NamespaceIndex); root.DisplayName = root.BrowseName.Name; root.TypeDefinitionId = ObjectTypeIds.FolderType; // ensure root can be found via the server object. IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } root.AddReference(ReferenceTypeIds.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, root.NodeId)); // save the node for later lookup. AddPredefinedNode(SystemContext, root); #endregion #region Task #A2 - Create Object Instance with a Property // create the folder object. BaseObjectState instance = new BaseObjectState(null); instance.NodeId = GenerateNodeId(); instance.BrowseName = new QualifiedName("Object", NamespaceIndex); instance.DisplayName = instance.BrowseName.Name; instance.TypeDefinitionId = ObjectTypeIds.BaseObjectType; // create a losely coupled relationship with the root object. root.AddReference(ReferenceTypeIds.Organizes, false, instance.NodeId); instance.AddReference(ReferenceTypeIds.Organizes, true, root.NodeId); // create a property. PropertyState <int> property = new PropertyState <int>(instance); property.NodeId = GenerateNodeId(); property.BrowseName = new QualifiedName("Property", NamespaceIndex); property.DisplayName = property.BrowseName.Name; property.TypeDefinitionId = VariableTypeIds.PropertyType; property.DataType = DataTypeIds.Int32; property.ValueRank = ValueRanks.Scalar; property.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; property.AccessLevel = AccessLevels.CurrentReadOrWrite; property.UserAccessLevel = AccessLevels.CurrentReadOrWrite; property.Historizing = false; property.ReferenceTypeId = ReferenceTypeIds.HasProperty; // create a property that is tightly coupled. instance.AddChild(property); // save the node for later lookup (all tightly coupled children are added with this call). AddPredefinedNode(SystemContext, instance); #endregion #region Task #A3 - Create a Variable using the Built-in Type Model // create the variable. AnalogItemState <double> variable = new AnalogItemState <double>(instance); // add optional properties. variable.InstrumentRange = new PropertyState <Range>(variable); // instantiate based on the type model. assigns ids automatically using SystemContext.NodeIdFactory variable.Create( SystemContext, GenerateNodeId(), new QualifiedName("Variable", NamespaceIndex), null, true); // set default values. variable.EURange.Value = new Range(90, 10); variable.InstrumentRange.Value = new Range(100, 0); // tightly coupled. instance.AddChild(variable); // need to add it manually since its parent was already added. AddPredefinedNode(SystemContext, variable); #endregion #region Task #A4 - Add Dynamic Behavoir by Updating In-Memory Nodes m_property = property; m_simulationTimer = new Timer(DoSimulation, null, 1000, 1000); #endregion #region Task #A5 - Add Support for External Nodes // External nodes are nodes that reference an entity which stored elsewhere. // These nodes use no memory in the server unless they are accessed. // The NodeId is a string that is used to create the external node on demand. root.AddReference(ReferenceTypeIds.Organizes, false, CreateNodeId("Alpha")); root.AddReference(ReferenceTypeIds.Organizes, false, CreateNodeId("Omega")); #endregion #region Task #A7 - Add Support for Method MethodState method = new MethodState(instance); method.NodeId = GenerateNodeId(); method.BrowseName = new QualifiedName("Method", NamespaceIndex); method.DisplayName = method.BrowseName.Name; method.Executable = true; method.UserExecutable = true; method.ReferenceTypeId = ReferenceTypeIds.HasComponent; instance.AddChild(method); // create the input arguments. PropertyState <Argument[]> inputArguments = new PropertyState <Argument[]>(method); inputArguments.NodeId = GenerateNodeId(); inputArguments.BrowseName = new QualifiedName(BrowseNames.InputArguments); inputArguments.DisplayName = inputArguments.BrowseName.Name; inputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; inputArguments.DataType = DataTypeIds.Argument; inputArguments.ValueRank = ValueRanks.OneDimension; inputArguments.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; inputArguments.AccessLevel = AccessLevels.CurrentRead; inputArguments.UserAccessLevel = AccessLevels.CurrentRead; inputArguments.Historizing = false; inputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; inputArguments.Value = new Argument[] { new Argument() { Name = "CurrentCount", Description = "The current count.", DataType = DataTypeIds.Int32, ValueRank = ValueRanks.Scalar } }; method.InputArguments = inputArguments; // create the output arguments. PropertyState <Argument[]> outputArguments = new PropertyState <Argument[]>(method); outputArguments.NodeId = GenerateNodeId(); outputArguments.BrowseName = new QualifiedName(BrowseNames.OutputArguments); outputArguments.DisplayName = outputArguments.BrowseName.Name; outputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; outputArguments.DataType = DataTypeIds.Argument; outputArguments.ValueRank = ValueRanks.OneDimension; outputArguments.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; outputArguments.AccessLevel = AccessLevels.CurrentRead; outputArguments.UserAccessLevel = AccessLevels.CurrentRead; outputArguments.Historizing = false; outputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; outputArguments.Value = new Argument[] { new Argument() { Name = "NewCount", Description = "The new count.", DataType = DataTypeIds.Int32, ValueRank = ValueRanks.Scalar } }; method.OutputArguments = outputArguments; // save the node for later lookup (all tightly coupled children are added with this call). AddPredefinedNode(SystemContext, instance); // register handler. method.OnCallMethod = new GenericMethodCalledEventHandler(DoMethodCall); #endregion #region Task #D6 - Add Support for Notifiers // enable subscriptions. root.EventNotifier = EventNotifiers.SubscribeToEvents; // creating notifier ensures events propogate up the hierarchy when the are produced. AddRootNotifier(root); // add link to server object. if (!externalReferences.TryGetValue(ObjectIds.Server, out references)) { externalReferences[ObjectIds.Server] = references = new List <IReference>(); } references.Add(new NodeStateReference(ReferenceTypeIds.HasNotifier, false, root.NodeId)); // add sub-notifiers. instance.EventNotifier = EventNotifiers.SubscribeToEvents; instance.AddNotifier(SystemContext, ReferenceTypeIds.HasNotifier, true, root); root.AddNotifier(SystemContext, ReferenceTypeIds.HasNotifier, false, instance); #endregion } }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case DsatsDemo.BrowseNames.MaxRPM: { if (createOrReplace) { if (MaxRPM == null) { if (replacement == null) { MaxRPM = new AnalogItemState<float>(this); } else { MaxRPM = (AnalogItemState<float>)replacement; } } } instance = MaxRPM; break; } case DsatsDemo.BrowseNames.MinRPM: { if (createOrReplace) { if (MinRPM == null) { if (replacement == null) { MinRPM = new AnalogItemState<float>(this); } else { MinRPM = (AnalogItemState<float>)replacement; } } } instance = MinRPM; break; } case DsatsDemo.BrowseNames.MaxTorque: { if (createOrReplace) { if (MaxTorque == null) { if (replacement == null) { MaxTorque = new AnalogItemState<float>(this); } else { MaxTorque = (AnalogItemState<float>)replacement; } } } instance = MaxTorque; break; } case DsatsDemo.BrowseNames.MinTorque: { if (createOrReplace) { if (MinTorque == null) { if (replacement == null) { MinTorque = new AnalogItemState<float>(this); } else { MinTorque = (AnalogItemState<float>)replacement; } } } instance = MinTorque; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Creates a variable from a tag. /// </summary> /// <param name="context">The context.</param> /// <param name="tag">The tag.</param> /// <returns>The variable that represents the tag.</returns> private BaseVariableState CreateVariable(ISystemContext context, UnderlyingSystemTag tag) { // create the variable type based on the tag type. BaseDataVariableState variable = null; switch (tag.TagType) { case UnderlyingSystemTagType.Analog: { AnalogItemState node = new AnalogItemState(this); if (tag.EngineeringUnits != null) { node.EngineeringUnits = new PropertyState<EUInformation>(node); } if (tag.EuRange.Length >= 4) { node.InstrumentRange = new PropertyState<Range>(node); } variable = node; break; } case UnderlyingSystemTagType.Digital: { TwoStateDiscreteState node = new TwoStateDiscreteState(this); variable = node; break; } case UnderlyingSystemTagType.Enumerated: { MultiStateDiscreteState node = new MultiStateDiscreteState(this); if (tag.Labels != null) { node.EnumStrings = new PropertyState<LocalizedText[]>(node); } variable = node; break; } default: { DataItemState node = new DataItemState(this); variable = node; break; } } // set the symbolic name and reference types. variable.SymbolicName = tag.Name; variable.ReferenceTypeId = ReferenceTypeIds.HasComponent; // initialize the variable from the type model. variable.Create( context, null, new QualifiedName(tag.Name, this.BrowseName.NamespaceIndex), null, true); // update the variable values. UpdateVariable(context, tag, variable); return variable; }
private DataItemState CreateAnalogItemVariable(NodeState parent, string path, string name, NodeId dataType, int valueRank, object initialValues, Range customRange) { AnalogItemState variable = new AnalogItemState(parent); variable.BrowseName = new QualifiedName(path, NamespaceIndex); variable.EngineeringUnits = new PropertyState<EUInformation>(variable); variable.InstrumentRange = new PropertyState<Range>(variable); variable.Create( SystemContext, new NodeId(path, NamespaceIndex), variable.BrowseName, null, true); variable.NodeId = new NodeId(path, NamespaceIndex); variable.SymbolicName = name; variable.DisplayName = new LocalizedText("en", name); variable.WriteMask = AttributeWriteMask.None; variable.UserWriteMask = AttributeWriteMask.None; variable.ReferenceTypeId = ReferenceTypes.Organizes; variable.DataType = dataType; variable.ValueRank = valueRank; variable.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variable.Historizing = false; if (customRange != null) { variable.EURange.Value = customRange; } else { variable.EURange.Value = new Range(100, 0); } variable.InstrumentRange.Value = new Range(120, -10); if (initialValues == null) { variable.Value = Opc.Ua.TypeInfo.GetDefaultValue(dataType, valueRank, Server.TypeTree); } else { variable.Value = initialValues; } variable.StatusCode = StatusCodes.Good; variable.Timestamp = DateTime.UtcNow; variable.EngineeringUnits.Value = new EUInformation("liters", Namespaces.ReferenceApplications); variable.OnWriteValue = OnWriteAnalog; variable.EURange.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.EURange.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variable.EngineeringUnits.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.EngineeringUnits.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variable.InstrumentRange.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.InstrumentRange.UserAccessLevel = AccessLevels.CurrentReadOrWrite; if (parent != null) { parent.AddChild(variable); } return variable; }
/// <summary> /// Updates a variable from a tag. /// </summary> /// <param name="context">The context.</param> /// <param name="tag">The tag.</param> /// <param name="variable">The variable to update.</param> private void UpdateVariable(ISystemContext context, UnderlyingSystemTag tag, BaseVariableState variable) { variable.Description = tag.Description; variable.Value = tag.Value; variable.Timestamp = tag.Timestamp; switch (tag.DataType) { case UnderlyingSystemDataType.Integer1: { variable.DataType = DataTypes.SByte; break; } case UnderlyingSystemDataType.Integer2: { variable.DataType = DataTypes.Int16; break; } case UnderlyingSystemDataType.Integer4: { variable.DataType = DataTypes.Int32; break; } case UnderlyingSystemDataType.Real4: { variable.DataType = DataTypes.Float; break; } case UnderlyingSystemDataType.String: { variable.DataType = DataTypes.String; break; } } variable.ValueRank = ValueRanks.Scalar; variable.ArrayDimensions = null; if (tag.IsWriteable) { variable.AccessLevel = AccessLevels.CurrentReadOrWrite; variable.UserAccessLevel = AccessLevels.CurrentReadOrWrite; } else { variable.AccessLevel = AccessLevels.CurrentRead; variable.UserAccessLevel = AccessLevels.CurrentRead; } variable.MinimumSamplingInterval = MinimumSamplingIntervals.Continuous; variable.Historizing = false; switch (tag.TagType) { case UnderlyingSystemTagType.Analog: { AnalogItemState node = variable as AnalogItemState; if (tag.EuRange != null) { if (tag.EuRange.Length >= 2 && node.EURange != null) { Range range = new Range(tag.EuRange[0], tag.EuRange[1]); node.EURange.Value = range; node.EURange.Timestamp = tag.Block.Timestamp; } if (tag.EuRange.Length >= 4 && node.InstrumentRange != null) { Range range = new Range(tag.EuRange[2], tag.EuRange[3]); node.InstrumentRange.Value = range; node.InstrumentRange.Timestamp = tag.Block.Timestamp; } } if (!String.IsNullOrEmpty(tag.EngineeringUnits) && node.EngineeringUnits != null) { EUInformation info = new EUInformation(); info.DisplayName = tag.EngineeringUnits; info.NamespaceUri = Namespaces.HistoricalAccess; node.EngineeringUnits.Value = info; node.EngineeringUnits.Timestamp = tag.Block.Timestamp; } break; } case UnderlyingSystemTagType.Digital: { TwoStateDiscreteState node = variable as TwoStateDiscreteState; if (tag.Labels != null && node.TrueState != null && node.FalseState != null) { if (tag.Labels.Length >= 2) { node.TrueState.Value = new LocalizedText(tag.Labels[0]); node.TrueState.Timestamp = tag.Block.Timestamp; node.FalseState.Value = new LocalizedText(tag.Labels[1]); node.FalseState.Timestamp = tag.Block.Timestamp; } } break; } case UnderlyingSystemTagType.Enumerated: { MultiStateDiscreteState node = variable as MultiStateDiscreteState; if (tag.Labels != null) { LocalizedText[] strings = new LocalizedText[tag.Labels.Length]; for (int ii = 0; ii < tag.Labels.Length; ii++) { strings[ii] = new LocalizedText(tag.Labels[ii]); } node.EnumStrings.Value = strings; node.EnumStrings.Timestamp = tag.Block.Timestamp; } break; } } }
/// <summary> /// Finds the child with the specified browse name. /// </summary> /// <param name="context">The system context.</param> /// <param name="browseName">The browse name.</param> /// <param name="createOrReplace">A flag that specifies the action: to create or to replace.</param> /// <param name="replacement">The replacement.</param> /// <returns>The instance state found; or NULL otherwise.</returns> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case ITG3200.BrowseNames.GyroX: { if (createOrReplace) { if (GyroX == null) { if (replacement == null) { GyroX = new AnalogItemState <double>(this); } else { GyroX = (AnalogItemState <double>)replacement; } } } instance = GyroX; break; } case ITG3200.BrowseNames.GyroY: { if (createOrReplace) { if (GyroY == null) { if (replacement == null) { GyroY = new AnalogItemState <double>(this); } else { GyroY = (AnalogItemState <double>)replacement; } } } instance = GyroY; break; } case ITG3200.BrowseNames.GyroZ: { if (createOrReplace) { if (GyroZ == null) { if (replacement == null) { GyroZ = new AnalogItemState <double>(this); } else { GyroZ = (AnalogItemState <double>)replacement; } } } instance = GyroZ; break; } case ITG3200.BrowseNames.Temperature: { if (createOrReplace) { if (Temperature == null) { if (replacement == null) { Temperature = new AnalogItemState <double>(this); } else { Temperature = (AnalogItemState <double>)replacement; } } } instance = Temperature; break; } case ITG3200.BrowseNames.Online: { if (createOrReplace) { if (Online == null) { if (replacement == null) { Online = new DataItemState <bool>(this); } else { Online = (DataItemState <bool>)replacement; } } } instance = Online; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case Quickstarts.HistoricalEvents.BrowseNames.TestDuration: { if (createOrReplace) { if (TestDuration == null) { if (replacement == null) { TestDuration = new AnalogItemState <double>(this); } else { TestDuration = (AnalogItemState <double>)replacement; } } } instance = TestDuration; break; } case Quickstarts.HistoricalEvents.BrowseNames.InjectedFluid: { if (createOrReplace) { if (InjectedFluid == null) { if (replacement == null) { InjectedFluid = new PropertyState <string>(this); } else { InjectedFluid = (PropertyState <string>)replacement; } } } instance = InjectedFluid; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }
/// <summary> /// Returns the value as a percentage of the range. /// </summary> private double GetPercentage(AnalogItemState<double> value) { double percentage = value.Value; Range range = value.EURange.Value; if (range != null) { percentage /= Math.Abs(range.High - range.Low); if (Math.Abs(percentage) > 1.0) { percentage = 1.0; } } return percentage; }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return null; } BaseInstanceState instance = null; switch (browseName.Name) { case FileSystem.BrowseNames.Humidity: { if (createOrReplace) { if (Humidity == null) { if (replacement == null) { Humidity = new AnalogItemState<double>(this); } else { Humidity = (AnalogItemState<double>)replacement; } } } instance = Humidity; break; } case FileSystem.BrowseNames.HumiditySetPoint: { if (createOrReplace) { if (HumiditySetPoint == null) { if (replacement == null) { HumiditySetPoint = new AnalogItemState<double>(this); } else { HumiditySetPoint = (AnalogItemState<double>)replacement; } } } instance = HumiditySetPoint; break; } } if (instance != null) { return instance; } return base.FindChild(context, browseName, createOrReplace, replacement); }
/// <summary> /// Finds the child with the specified browse name. /// </summary> protected override BaseInstanceState FindChild( ISystemContext context, QualifiedName browseName, bool createOrReplace, BaseInstanceState replacement) { if (QualifiedName.IsNull(browseName)) { return(null); } BaseInstanceState instance = null; switch (browseName.Name) { case SampleCompany.SampleServer.Model.BrowseNames.SetPoint: { if (createOrReplace) { if (SetPoint == null) { if (replacement == null) { SetPoint = new AnalogItemState <double>(this); } else { SetPoint = (AnalogItemState <double>)replacement; } } } instance = SetPoint; break; } case SampleCompany.SampleServer.Model.BrowseNames.Measurement: { if (createOrReplace) { if (Measurement == null) { if (replacement == null) { Measurement = new AnalogItemState <double>(this); } else { Measurement = (AnalogItemState <double>)replacement; } } } instance = Measurement; break; } } if (instance != null) { return(instance); } return(base.FindChild(context, browseName, createOrReplace, replacement)); }