/// <summary> /// 生成根节点(根节点单独处理方法) /// </summary> /// <param name="nodes"></param> /// <param name="references"></param> private void GeneraterNodes(List <OpcuaNode> nodes, IList <IReference> references) { var list = nodes.Where(d => d.NodeType == NodeType.Scada); foreach (var item in list) { try { FolderState root = CreateFolder(null, item.NodePath, item.NodeName); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); CreateNodes(nodes, root, item.NodePath); _folderDic.Add(item.NodePath, root); //添加引用关系 AddPredefinedNode(SystemContext, root); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("创建OPC-UA根节点触发异常:" + ex.Message); Console.ResetColor(); } } }
private void CreateDevice(ServerSystemContext context, FolderState folder) { m_device = new ITG3200State(folder); string name = "ITG3200"; m_device.Create( context, null, new QualifiedName(name, NamespaceIndex), null, true); folder.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, false, m_device.NodeId); m_device.AddReference(Opc.Ua.ReferenceTypeIds.Organizes, true, folder.NodeId); m_device.GyroX.Value = 0; m_device.GyroY.Value = 0; m_device.GyroZ.Value = 0; m_device.Temperature.Value = 0; m_device.Online.Value = false; AddPredefinedNode(context, m_device); try { m_device.InitI2CGyro(); } catch { // Trace } finally { m_simulationTimer = new Timer(RunReadDevice, null, 1000, 1000); } }
/// <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) { // create the refrigerator folder. FolderState folder = new FolderState(null); folder.NodeId = new NodeId("Devices", NamespaceIndex); folder.BrowseName = new QualifiedName("Devices", NamespaceIndex); folder.DisplayName = folder.BrowseName.Name; folder.TypeDefinitionId = Opc.Ua.ObjectTypeIds.FolderType; IList <IReference> references = null; if (!externalReferences.TryGetValue(Opc.Ua.ObjectIds.ObjectsFolder, out references)) { externalReferences[Opc.Ua.ObjectIds.ObjectsFolder] = references = new List <IReference>(); } references.Add(new NodeStateReference(ReferenceTypeIds.Organizes, false, folder.NodeId)); folder.AddReference(ReferenceTypeIds.Organizes, true, Opc.Ua.ObjectIds.ObjectsFolder); // save the node for later lookup. AddPredefinedNode(SystemContext, folder); // create the Device instance object CreateDevice(SystemContext, folder); } }
public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } ImportNodeset2Xml(externalReferences, "Station.NodeSet2.xml"); FolderState root = CreateFolder(null, "AssetAdminShell", "AssetAdminShell"); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); MethodState createAASMethod = CreateMethod(root, "GenerateAAS", "GenerateAAS"); createAASMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnGenerateAASCall); AddPredefinedNode(SystemContext, root); AddReverseReferences(externalReferences); } }
/// <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 (this.Lock) { if (!externalReferences.TryGetValue(key: ObjectIds.ObjectsFolder, value: out var references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } var folder = new FolderState(parent: null) { SymbolicName = nameof(OpcUaServerHelper), ReferenceTypeId = ReferenceTypes.Organizes, TypeDefinitionId = ObjectTypeIds.FolderType, NodeId = new NodeId(nameof(OpcUaServerHelper), this.NamespaceIndex), BrowseName = new QualifiedName(nameof(OpcUaServerHelper), this.NamespaceIndex), WriteMask = AttributeWriteMask.None, UserWriteMask = AttributeWriteMask.None, EventNotifier = EventNotifiers.None, DisplayName = new LocalizedText(Text.Locale, nameof(OpcUaServerHelper)) }; folder.AddReference(referenceTypeId: ReferenceTypes.Organizes, isInverse: true, targetId: ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(referenceTypeId: ReferenceTypes.Organizes, isInverse: false, targetId: folder.NodeId)); folder.EventNotifier = EventNotifiers.SubscribeToEvents; } }
/// <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); // ensure trigger can be found via the server object. IList <IReference> references = null; if (!externalReferences.TryGetValue(Opc.Ua.ObjectIds.ObjectsFolder, out references)) { externalReferences[Opc.Ua.ObjectIds.ObjectsFolder] = references = new List <IReference>(); } FolderState root = CreateFolder(null, "CitiesNodes", "CitiesNodes"); root.AddReference(ReferenceTypes.Organizes, true, Opc.Ua.ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; root.Description = "A folder containing data sources"; AddRootNotifier(root); try { SetupNodes(); FolderState citiesNodes = CreateFolder(root, "Cities", "Cities"); citiesNodes.Description = "This folder contains nodes of the city stations"; WeatherMapVariableState catania = CreateVariable(citiesNodes, "Catania", "Catania", new NodeId(DataTypeIds.WeatherData.Identifier, DataTypeIds.WeatherData.NamespaceIndex), ValueRanks.Scalar); List <BaseVariableState> childCatania = CreateChild(catania); WeatherMapVariableState palermo = CreateVariable(citiesNodes, "Palermo", "Palermo", new NodeId(DataTypeIds.WeatherData.Identifier, DataTypeIds.WeatherData.NamespaceIndex), ValueRanks.Scalar); List <BaseVariableState> childPalermo = CreateChild(palermo); WeatherMapVariableState messina = CreateVariable(citiesNodes, "Messina", "Messina", new NodeId(DataTypeIds.WeatherData.Identifier, DataTypeIds.WeatherData.NamespaceIndex), ValueRanks.Scalar); List <BaseVariableState> childMessina = CreateChild(messina); variables.Add(palermo, childPalermo); variables.Add(messina, childMessina); variables.Add(catania, childCatania); } catch (Exception e) { Utils.Trace(e, "MyOPCServer: Error creating the address space."); } AddPredefinedNode(SystemContext, root); //variable.SetChildValue(SystemContext,BrowseNames.Temperature, variable.Value.Temperature, false); } }
/// <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) { IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } FolderState root = CreateFolder(null, "OpcPublisher", "OpcPublisher"); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); List <BaseDataVariableState> variables = new List <BaseDataVariableState>(); try { #region DataAccess_DataItem FolderState dataFolder = CreateFolder(root, "Data", "Data"); const string connectionStringItemName = "ConnectionString"; DataItemState item = CreateDataItemVariable(dataFolder, connectionStringItemName, connectionStringItemName, BuiltInType.String, ValueRanks.Scalar, AccessLevels.CurrentWrite); item.Value = String.Empty; #endregion #region Methods FolderState methodsFolder = CreateFolder(root, "Methods", "Methods"); #region PublishNode Method MethodState publishNodeMethod = CreateMethod(methodsFolder, "PublishNode", "PublishNode"); SetPublishNodeMethodProperties(ref publishNodeMethod); #endregion #region UnpublishNode Method MethodState unpublishNodeMethod = CreateMethod(methodsFolder, "UnpublishNode", "UnpublishNode"); SetUnpublishNodeMethodProperties(ref unpublishNodeMethod); #endregion #region GetListOfPublishedNodes Method MethodState getListOfPublishedNodesMethod = CreateMethod(methodsFolder, "GetListOfPublishedNodes", "GetListOfPublishedNodes"); SetGetListOfPublishedNodesMethodProperties(ref getListOfPublishedNodesMethod); #endregion #endregion Methods } catch (Exception e) { Utils.Trace(e, "Error creating the address space."); } AddPredefinedNode(SystemContext, root); } }
/// <summary> /// Creates address space from JSON config file. /// </summary> /// <param name="externalReferences"></param> public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } string json; using (StreamReader sw = new StreamReader(this._nodeFile)) { json = sw.ReadToEnd(); } ConfigFolder cfgFolder = JsonConvert.DeserializeObject <ConfigFolder>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); FolderState folderFromConfigFile = CreateFolder(null, cfgFolder.Name, cfgFolder.Name); folderFromConfigFile.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, folderFromConfigFile.NodeId)); folderFromConfigFile.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(folderFromConfigFile); Logger.Information($""); Logger.Information($"{nameof(PlcNodeManagerFromFile)} bootstrap started."); Logger.Information($"{nameof(PlcNodeManagerFromFile)} created folder {cfgFolder.Name} in namespace {cfgFolder.NamespaceId}."); foreach (var node in cfgFolder.NodeList) { CreateBaseVariable(folderFromConfigFile, node); Logger.Information($"{nameof(PlcNodeManagerFromFile)} created node {node.NodeId} - {node.Name}."); } FolderState root = CreateFolder(null, ProgramName, ProgramName); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); AddPredefinedNode(SystemContext, folderFromConfigFile); Logger.Information($"{nameof(PlcNodeManagerFromFile)} bootstrap completed."); Logger.Information($""); } base.CreateAddressSpace(externalReferences); }
/// <summary> /// Gets the item configuration node. /// </summary> /// <param name="itemId">The item id.</param> /// <param name="namespaceIndex">Index of the namespace.</param> /// <returns></returns> public static BaseInstanceState GetItemConfigurationNode(string itemId, ushort namespaceIndex) { if (itemId == null) { return(null); } FolderState component = new FolderState(null); component.NodeId = HdaParsedNodeId.Construct(HdaModelUtils.HdaItemConfiguration, itemId, null, namespaceIndex); component.SymbolicName = Opc.Ua.BrowseNames.HAConfiguration; component.BrowseName = new QualifiedName(component.SymbolicName); component.DisplayName = component.BrowseName.Name; component.ReferenceTypeId = Opc.Ua.ReferenceTypeIds.HasComponent; component.TypeDefinitionId = Opc.Ua.ObjectTypeIds.HistoricalDataConfigurationType; component.EventNotifier = EventNotifiers.None; component.AddReference(ReferenceTypeIds.HasHistoricalConfiguration, true, HdaModelUtils.ConstructIdForHdaItem(itemId, namespaceIndex)); component.AddReference(ReferenceTypeIds.HasComponent, false, HdaModelUtils.ConstructIdForInternalNode(Opc.Ua.BrowseNames.AggregateConfiguration, namespaceIndex)); return(component); }
/// <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) { var rootName = "TestData"; FolderState root = NewFolder(rootName, null); // ensure trigger 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)); m_dynamicVars = new List <BaseDataVariableState>(); foreach (var v in m_variables) { var vv = CreateAnalogItemVariable(root, rootName + "_" + v.Key, v.Key, (uint)v.Value); m_dynamicVars.Add(vv); } // save in dictionary. AddPredefinedNode(SystemContext, root); /* * ReferenceTypeState referenceType = new ReferenceTypeState(); * * referenceType.NodeId = new NodeId(3, NamespaceIndex); * referenceType.BrowseName = new QualifiedName("IsTriggerSource", NamespaceIndex); * referenceType.DisplayName = referenceType.BrowseName.Name; * referenceType.InverseName = new LocalizedText("IsSourceOfTrigger"); * referenceType.SuperTypeId = ReferenceTypeIds.NonHierarchicalReferences; * * if (!externalReferences.TryGetValue(ObjectIds.Server, out references)) * { * externalReferences[ObjectIds.Server] = references = new List<IReference>(); * } * * trigger.AddReference(referenceType.NodeId, false, ObjectIds.Server); * references.Add(new NodeStateReference(referenceType.NodeId, true, trigger.NodeId)); * * // save in dictionary. * AddPredefinedNode(SystemContext, referenceType); */ } }
/// <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) { IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } var myNodeFactory = new NodeFactory(this); try { LoadPredefinedNodes(SystemContext, externalReferences); // start a simulation that changes the values of the nodes. //// Folder to organize the refrigerator FolderState refrigeratorOrganizer = myNodeFactory.CreateFolder(null, "Refrigerators", "Refrigerators", NamespaceIndex); refrigeratorOrganizer.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, refrigeratorOrganizer.NodeId)); AddRootNotifier(refrigeratorOrganizer); // Add Refrigerators for (int i = 1; i <= 5; i++) { var fridgeFactory = new RefrigeratorFactory(refrigeratorOrganizer, "Refrigerator " + i, this); m_refrigeratorBuffer.Add(fridgeFactory, new Timer(AttachTemperatureSimulator, fridgeFactory, 5000, 5000)); } AddPredefinedNode(SystemContext, refrigeratorOrganizer); //// Folder to organize the boiler FolderState boilerOrganizer = myNodeFactory.CreateFolder(null, "Boilers", "Boilers", NamespaceIndex); boilerOrganizer.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, boilerOrganizer.NodeId)); AddRootNotifier(boilerOrganizer); //// Add Boiler for (uint i = 1; i <= 5; i++) { var boilerFactory = new BoilerFactory(boilerOrganizer, "Boiler" + i, this, i); m_boilerBuffer.Add(boilerFactory, null); } AddPredefinedNode(SystemContext, boilerOrganizer); } catch (Exception e) { Utils.Trace(Utils.TraceMasks.Error, e.Message, ""); } } }
/// <summary> /// Does any initialization required before the address space can be used. /// </summary> /// <remarks> /// The externalReferences is an out parameter that allows the node manager to link to nodes /// in other node managers. For example, the 'Objects' node is managed by the CoreNodeManager and /// should have a reference to the root folder node(s) exposed by this node manager. /// </remarks> public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out IList <IReference> references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } FolderState root = CreateFolder(null, ProgramName, ProgramName, NamespaceType.OpcPlcApplications); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); var variables = new List <BaseDataVariableState>(); try { FolderState dataFolder = CreateFolder(root, "Telemetry", "Telemetry", NamespaceType.OpcPlcApplications); AddChangingNodes(dataFolder); AddSlowAndFastNodes(dataFolder); FolderState methodsFolder = CreateFolder(root, "Methods", "Methods", NamespaceType.OpcPlcApplications); AddMethods(methodsFolder); AddUserConfigurableNodes(root); AddComplexTypeBoiler(methodsFolder, externalReferences); AddSpecialNodes(dataFolder); } catch (Exception e) { Logger.Error(e, "Error creating the address space."); } AddPredefinedNode(SystemContext, root); } }
/// <summary> /// Creates node for Signal associated to Component in Visual Components. /// </summary> private BaseDataVariableState CreateVariableNode(FolderState parentFolder, string nodeName, NodeId nodeDataType) { string namespaceUri = Namespaces.vc2opcua; string nodeNameParent = String.Format("{0}-{1}", nodeName, parentFolder.Parent.DisplayName); BaseDataVariableState variableNode = new BaseDataVariableState(parentFolder); NodeId nodeId = NodeId.Create(nodeNameParent, namespaceUri, uaServer.NamespaceUris); variableNode.Create( nodeManager.context, nodeId, new QualifiedName(nodeNameParent, (ushort)uaServer.NamespaceUris.GetIndex(namespaceUri)), new LocalizedText(nodeName), true); variableNode.DataType = nodeDataType; parentFolder.AddReference(ReferenceTypeIds.Organizes, false, variableNode.NodeId); variableNode.AddReference(ReferenceTypeIds.Organizes, true, parentFolder.NodeId); return(variableNode); }
/// <summary> /// Does any initialization required before the address space can be used. /// </summary> public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { try { Monitor.Enter(dataLock); // create the root folder if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out IList <IReference> references)) { references = new List <IReference>(); externalReferences[ObjectIds.ObjectsFolder] = references; } FolderState rootFolder = CreateFolder(null, RootFolderName, RootFolderName); rootFolder.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, rootFolder.NodeId)); rootFolder.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(rootFolder); // create child nodes varByDevice = new Dictionary <int, DeviceVars>(); varByPath = new Dictionary <string, VarItem>(); CreateChildNodes(rootFolder); // recursively index the node AddPredefinedNode(SystemContext, rootFolder); } catch (Exception ex) { log.WriteException(ex, Locale.IsRussian ? "Ошибка при создании адресного пространства" : "Error creating address space"); throw; } finally { Monitor.Exit(dataLock); } }
/// <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> /// Adds an aggregate function to the server capabilities object. /// </summary> public void AddAggregateFunction(NodeId aggregateId, string aggregateName, bool isHistorical) { lock (Lock) { FolderState state = new FolderState(null); state.SymbolicName = aggregateName; state.ReferenceTypeId = ReferenceTypes.HasComponent; state.TypeDefinitionId = ObjectTypeIds.AggregateFunctionType; state.NodeId = aggregateId; state.BrowseName = new QualifiedName(aggregateName, aggregateId.NamespaceIndex); state.DisplayName = state.BrowseName.Name; state.WriteMask = AttributeWriteMask.None; state.UserWriteMask = AttributeWriteMask.None; state.EventNotifier = EventNotifiers.None; NodeState folder = FindPredefinedNode(ObjectIds.Server_ServerCapabilities_AggregateFunctions, typeof(BaseObjectState)); if (folder != null) { folder.AddReference(ReferenceTypes.Organizes, false, state.NodeId); state.AddReference(ReferenceTypes.Organizes, true, folder.NodeId); } if (isHistorical) { folder = FindPredefinedNode(ObjectIds.HistoryServerCapabilities_AggregateFunctions, typeof(BaseObjectState)); if (folder != null) { folder.AddReference(ReferenceTypes.Organizes, false, state.NodeId); state.AddReference(ReferenceTypes.Organizes, true, folder.NodeId); } } AddPredefinedNode(SystemContext, state); } }
/// <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) { LoadPredefinedNodes(SystemContext, externalReferences); IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } FolderState rootMy = CreateFolder(null, "Machines"); rootMy.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, rootMy.NodeId)); rootMy.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(rootMy); string[] machines = new string[] { "Machine A", "Machine B", "Machine C" }; list = new List <BaseDataVariableState <int> >(); for (int i = 0; i < machines.Length; i++) { FolderState myFolder = CreateFolder(rootMy, machines[i]); CreateVariable(myFolder, "Name", DataTypeIds.String, ValueRanks.Scalar, "测试数据").Description = "设备的名称"; CreateVariable(myFolder, "IsFault", DataTypeIds.Boolean, ValueRanks.Scalar, true).Description = "设备是否启动"; CreateVariable(myFolder, "TestValueFloat", DataTypeIds.Float, ValueRanks.Scalar, 100.5f); CreateVariable(myFolder, "AlarmTime", DataTypeIds.DateTime, ValueRanks.Scalar, DateTime.Now); list.Add(CreateVariable(myFolder, "TestValueInt", DataTypeIds.Int32, ValueRanks.Scalar, 47123)); #region Add Method MethodState addMethod = CreateMethod(myFolder, "Calculate"); // set input arguments addMethod.InputArguments = new PropertyState <Argument[]>(addMethod) { NodeId = new NodeId(addMethod.BrowseName.Name + "InArgs", NamespaceIndex), BrowseName = BrowseNames.InputArguments }; addMethod.InputArguments.DisplayName = addMethod.InputArguments.BrowseName.Name; addMethod.InputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; addMethod.InputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; addMethod.InputArguments.DataType = DataTypeIds.Argument; addMethod.InputArguments.ValueRank = ValueRanks.OneDimension; addMethod.InputArguments.Value = new Argument[] { new Argument() { Name = "Int32 value", Description = "Int32 value", DataType = DataTypeIds.Int32, ValueRank = ValueRanks.Scalar }, new Argument() { Name = "Int32 value", Description = "Int32 value", DataType = DataTypeIds.Int32, ValueRank = ValueRanks.Scalar } }; // set output arguments addMethod.OutputArguments = new PropertyState <Argument[]>(addMethod); addMethod.OutputArguments.NodeId = new NodeId(addMethod.BrowseName.Name + "OutArgs", NamespaceIndex); addMethod.OutputArguments.BrowseName = BrowseNames.OutputArguments; addMethod.OutputArguments.DisplayName = addMethod.OutputArguments.BrowseName.Name; addMethod.OutputArguments.TypeDefinitionId = VariableTypeIds.PropertyType; addMethod.OutputArguments.ReferenceTypeId = ReferenceTypeIds.HasProperty; addMethod.OutputArguments.DataType = DataTypeIds.Argument; addMethod.OutputArguments.ValueRank = ValueRanks.OneDimension; addMethod.OutputArguments.Value = new Argument[] { new Argument() { Name = "Operater Result", Description = "Operater Result", DataType = DataTypeIds.String, ValueRank = ValueRanks.Scalar } }; addMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnAddCall); #endregion } SystemState = CreateVariable(rootMy, "Enable", DataTypeIds.Boolean, ValueRanks.Scalar, false); CreateVariable(rootMy, "Mat", DataTypeIds.Double, ValueRanks.TwoDimensions, new double[4, 4]); AddPredefinedNode(SystemContext, rootMy); FolderState robots = CreateFolder(null, "Robots"); robots.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, robots.NodeId)); robots.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(robots); RobotA = new HuiBoRobot(robots, "RobotA", NamespaceIndex, SystemContext); RobotB = new HuiBoRobot(robots, "RobotB", NamespaceIndex, SystemContext); RobotC = new HuiBoRobot(robots, "RobotC", NamespaceIndex, SystemContext); AddPredefinedNode(SystemContext, robots); } }
/// <summary> /// 修改节点树(添加节点,删除节点,修改节点名称) /// </summary> /// <param name="nodes"></param> public void UpdateNodesAttribute(List <OpcuaNode> nodes) { //修改或创建根节点 var scadas = nodes.Where(d => d.NodeType == NodeType.Scada); foreach (var item in scadas) { FolderState scadaNode = null; if (!_folderDic.TryGetValue(item.NodePath, out scadaNode)) { //如果根节点都不存在 那么整个树都需要创建 FolderState root = CreateFolder(null, item.NodePath, item.NodeName); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); _references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); CreateNodes(nodes, root, item.NodePath); _folderDic.Add(item.NodePath, root); AddPredefinedNode(SystemContext, root); continue; } else { scadaNode.DisplayName = item.NodeName; scadaNode.ClearChangeMasks(SystemContext, false); } } //修改或创建目录(此处设计为可以有多级目录,上面是演示数据,所以我只写了三级,事实上更多级也是可以的) var folders = nodes.Where(d => d.NodeType != NodeType.Scada && !d.IsTerminal); foreach (var item in folders) { FolderState folder = null; if (!_folderDic.TryGetValue(item.NodePath, out folder)) { var par = GetParentFolderState(nodes, item); folder = CreateFolder(par, item.NodePath, item.NodeName); AddPredefinedNode(SystemContext, folder); par.ClearChangeMasks(SystemContext, false); _folderDic.Add(item.NodePath, folder); } else { folder.DisplayName = item.NodeName; folder.ClearChangeMasks(SystemContext, false); } } //修改或创建测点 //这里我的数据结构采用IsTerminal来代表是否是测点 实际业务中可能需要根据自身需要调整 var paras = nodes.Where(d => d.IsTerminal); foreach (var item in paras) { BaseDataVariableState node = null; if (_nodeDic.TryGetValue(item.NodeId.ToString(), out node)) { node.DisplayName = item.NodeName; node.Timestamp = DateTime.Now; node.ClearChangeMasks(SystemContext, false); } else { FolderState folder = null; if (_folderDic.TryGetValue(item.ParentPath, out folder)) { node = CreateVariable(folder, item.NodePath, item.NodeName, DataTypeIds.Double, ValueRanks.Scalar); AddPredefinedNode(SystemContext, node); folder.ClearChangeMasks(SystemContext, false); _nodeDic.Add(item.NodeId.ToString(), node); } } } /* * 将新获取到的菜单列表与原列表对比 * 如果新菜单列表中不包含原有的菜单 * 则说明这个菜单被删除了 这里也需要删除 */ List <string> folderPath = _folderDic.Keys.ToList(); List <string> nodePath = _nodeDic.Keys.ToList(); var remNode = nodePath.Except(nodes.Where(d => d.IsTerminal).Select(d => d.NodeId.ToString())); foreach (var str in remNode) { BaseDataVariableState node = null; if (_nodeDic.TryGetValue(str, out node)) { var parent = node.Parent; parent.RemoveChild(node); _nodeDic.Remove(str); } } var remFolder = folderPath.Except(nodes.Where(d => !d.IsTerminal).Select(d => d.NodePath)); foreach (string str in remFolder) { FolderState folder = null; if (_folderDic.TryGetValue(str, out folder)) { var parent = folder.Parent; if (parent != null) { parent.RemoveChild(folder); _folderDic.Remove(str); } else { RemoveRootNotifier(folder); RemovePredefinedNode(SystemContext, folder, new List <LocalReference>()); } } } }
public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } FolderState root = CreateFolder(null, "Relais", "Relais"); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(root); List <BaseDataVariableState> variables = new List <BaseDataVariableState>(); try { #region Scalar_Static FolderState staticFolder = CreateFolder(root, "Virtual Inputs", "Virtual Inputs"); for (int i = 1; i < 65; i++) { variables.Add(CreateVariable(staticFolder, "SPCSO" + i.ToString(), "SPCSO" + i.ToString(), DataTypeIds.Boolean, ValueRanks.Scalar)); } #endregion #region AccessRights FolderState folderAccessRights = CreateFolder(root, "AccessRights", "AccessRights"); const string accessRights = "AccessRights_"; BaseDataVariableState accessRightsInstructions = CreateVariable(folderAccessRights, accessRights + "Instructions", "Instructions", DataTypeIds.String, ValueRanks.Scalar); accessRightsInstructions.Value = "This folder will be accessible to all who enter, but contents therein will be secured."; variables.Add(accessRightsInstructions); // sub-folder for "AccessAll" FolderState folderAccessRightsAccessAll = CreateFolder(folderAccessRights, "AccessRights_AccessAll", "AccessAll"); const string accessRightsAccessAll = "AccessRights_AccessAll_"; BaseDataVariableState arAllRO = CreateVariable(folderAccessRightsAccessAll, accessRightsAccessAll + "RO", "RO", BuiltInType.Int16, ValueRanks.Scalar); arAllRO.AccessLevel = AccessLevels.CurrentRead; arAllRO.UserAccessLevel = AccessLevels.CurrentRead; variables.Add(arAllRO); BaseDataVariableState arAllWO = CreateVariable(folderAccessRightsAccessAll, accessRightsAccessAll + "WO", "WO", BuiltInType.Int16, ValueRanks.Scalar); arAllWO.AccessLevel = AccessLevels.CurrentWrite; arAllWO.UserAccessLevel = AccessLevels.CurrentWrite; variables.Add(arAllWO); BaseDataVariableState arAllRW = CreateVariable(folderAccessRightsAccessAll, accessRightsAccessAll + "RW", "RW", BuiltInType.Int16, ValueRanks.Scalar); arAllRW.AccessLevel = AccessLevels.CurrentReadOrWrite; arAllRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variables.Add(arAllRW); BaseDataVariableState arAllROUserRW = CreateVariable(folderAccessRightsAccessAll, accessRightsAccessAll + "RO_User1_RW", "RO_User1_RW", BuiltInType.Int16, ValueRanks.Scalar); arAllROUserRW.AccessLevel = AccessLevels.CurrentRead; arAllROUserRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variables.Add(arAllROUserRW); BaseDataVariableState arAllROGroupRW = CreateVariable(folderAccessRightsAccessAll, accessRightsAccessAll + "RO_Group1_RW", "RO_Group1_RW", BuiltInType.Int16, ValueRanks.Scalar); arAllROGroupRW.AccessLevel = AccessLevels.CurrentRead; arAllROGroupRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variables.Add(arAllROGroupRW); // sub-folder for "AccessUser1" FolderState folderAccessRightsAccessUser1 = CreateFolder(folderAccessRights, "AccessRights_AccessUser1", "AccessUser1"); const string accessRightsAccessUser1 = "AccessRights_AccessUser1_"; BaseDataVariableState arUserRO = CreateVariable(folderAccessRightsAccessUser1, accessRightsAccessUser1 + "RO", "RO", BuiltInType.Int16, ValueRanks.Scalar); arUserRO.AccessLevel = AccessLevels.CurrentRead; arUserRO.UserAccessLevel = AccessLevels.CurrentRead; variables.Add(arUserRO); BaseDataVariableState arUserWO = CreateVariable(folderAccessRightsAccessUser1, accessRightsAccessUser1 + "WO", "WO", BuiltInType.Int16, ValueRanks.Scalar); arUserWO.AccessLevel = AccessLevels.CurrentWrite; arUserWO.UserAccessLevel = AccessLevels.CurrentWrite; variables.Add(arUserWO); BaseDataVariableState arUserRW = CreateVariable(folderAccessRightsAccessUser1, accessRightsAccessUser1 + "RW", "RW", BuiltInType.Int16, ValueRanks.Scalar); arUserRW.AccessLevel = AccessLevels.CurrentReadOrWrite; arUserRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variables.Add(arUserRW); // sub-folder for "AccessGroup1" FolderState folderAccessRightsAccessGroup1 = CreateFolder(folderAccessRights, "AccessRights_AccessGroup1", "AccessGroup1"); const string accessRightsAccessGroup1 = "AccessRights_AccessGroup1_"; BaseDataVariableState arGroupRO = CreateVariable(folderAccessRightsAccessGroup1, accessRightsAccessGroup1 + "RO", "RO", BuiltInType.Int16, ValueRanks.Scalar); arGroupRO.AccessLevel = AccessLevels.CurrentRead; arGroupRO.UserAccessLevel = AccessLevels.CurrentRead; variables.Add(arGroupRO); BaseDataVariableState arGroupWO = CreateVariable(folderAccessRightsAccessGroup1, accessRightsAccessGroup1 + "WO", "WO", BuiltInType.Int16, ValueRanks.Scalar); arGroupWO.AccessLevel = AccessLevels.CurrentWrite; arGroupWO.UserAccessLevel = AccessLevels.CurrentWrite; variables.Add(arGroupWO); BaseDataVariableState arGroupRW = CreateVariable(folderAccessRightsAccessGroup1, accessRightsAccessGroup1 + "RW", "RW", BuiltInType.Int16, ValueRanks.Scalar); arGroupRW.AccessLevel = AccessLevels.CurrentReadOrWrite; arGroupRW.UserAccessLevel = AccessLevels.CurrentReadOrWrite; variables.Add(arGroupRW); #endregion } catch (Exception e) { Utils.Trace(e, "Error creating the address space."); } AddPredefinedNode(SystemContext, root); } }
/// <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) { #region Setup IList <IReference> references = null; if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } #endregion try { #region Initialize string alarmsName = "Alarms"; string alarmsNodeName = alarmsName; Type alarmControllerType = Type.GetType("Alarms.AlarmController"); int interval = 1000; string intervalString = interval.ToString(); int conditionTypeIndex = 0; #endregion #region Create Alarm Folder FolderState alarmsFolder = CreateFolder(null, alarmsNodeName, alarmsName); alarmsFolder.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, alarmsFolder.NodeId)); alarmsFolder.EventNotifier = EventNotifiers.SubscribeToEvents; AddRootNotifier(alarmsFolder); #endregion #region Create Methods string startMethodName = "Start"; string startMethodNodeName = alarmsNodeName + "." + startMethodName; MethodState startMethod = AlarmHelpers.CreateMethod(alarmsFolder, NamespaceIndex, startMethodNodeName, startMethodName); AlarmHelpers.AddStartInputParameters(startMethod, NamespaceIndex); startMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnStart); string startBranchMethodName = "StartBranch"; string startBranchMethodNodeName = alarmsNodeName + "." + startBranchMethodName; MethodState startBranchMethod = AlarmHelpers.CreateMethod(alarmsFolder, NamespaceIndex, startBranchMethodNodeName, startBranchMethodName); AlarmHelpers.AddStartInputParameters(startBranchMethod, NamespaceIndex); startBranchMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnStartBranch); string endMethodName = "End"; string endMethodNodeName = alarmsNodeName + "." + endMethodName; MethodState endMethod = AlarmHelpers.CreateMethod(alarmsFolder, NamespaceIndex, endMethodNodeName, endMethodName); endMethod.OnCallMethod = new GenericMethodCalledEventHandler(OnEnd); #endregion #region Create Variables string analogTriggerName = "AnalogSource"; string analogTriggerNodeName = alarmsNodeName + "." + analogTriggerName; BaseDataVariableState analogTrigger = AlarmHelpers.CreateVariable(alarmsFolder, NamespaceIndex, analogTriggerNodeName, analogTriggerName); analogTrigger.OnWriteValue = OnWriteAlarmTrigger; AlarmController analogAlarmController = (AlarmController)Activator.CreateInstance(alarmControllerType, analogTrigger, interval, false); SourceController analogSourceController = new SourceController(analogTrigger, analogAlarmController); m_triggerMap.Add("Analog", analogSourceController); string booleanTriggerName = "BooleanSource"; string booleanTriggerNodeName = alarmsNodeName + "." + booleanTriggerName; BaseDataVariableState booleanTrigger = AlarmHelpers.CreateVariable(alarmsFolder, NamespaceIndex, booleanTriggerNodeName, booleanTriggerName, boolValue: true); booleanTrigger.OnWriteValue = OnWriteAlarmTrigger; AlarmController booleanAlarmController = (AlarmController)Activator.CreateInstance(alarmControllerType, booleanTrigger, interval, true); SourceController booleanSourceController = new SourceController(booleanTrigger, booleanAlarmController); m_triggerMap.Add("Boolean", booleanSourceController); #endregion #region Create Alarms AlarmHolder mandatoryExclusiveLevel = new ExclusiveLevelHolder( this, alarmsFolder, analogSourceController, intervalString, GetSupportedAlarmConditionType(ref conditionTypeIndex), alarmControllerType, interval, optional: false); m_alarms.Add(mandatoryExclusiveLevel.AlarmNodeName, mandatoryExclusiveLevel); AlarmHolder mandatoryNonExclusiveLevel = new NonExclusiveLevelHolder( this, alarmsFolder, analogSourceController, intervalString, GetSupportedAlarmConditionType(ref conditionTypeIndex), alarmControllerType, interval, optional: false); m_alarms.Add(mandatoryNonExclusiveLevel.AlarmNodeName, mandatoryNonExclusiveLevel); AlarmHolder offNormal = new OffNormalAlarmTypeHolder( this, alarmsFolder, booleanSourceController, intervalString, GetSupportedAlarmConditionType(ref conditionTypeIndex), alarmControllerType, interval, optional: false); m_alarms.Add(offNormal.AlarmNodeName, offNormal); #endregion AddPredefinedNode(SystemContext, alarmsFolder); StartTimer(); m_allowEntry = true; } catch (Exception e) { Utils.LogError(e, "Error creating the AlarmNodeManager address space."); } } }
// any initialization required before the address space can be used. public override void CreateAddressSpace(IDictionary <NodeId, IList <IReference> > externalReferences) { lock (Lock) { if (!externalReferences.TryGetValue(ObjectIds.ObjectsFolder, out IList <IReference> references)) { externalReferences[ObjectIds.ObjectsFolder] = references = new List <IReference>(); } FolderState root = CreateFolder(null, "CTT", "Test2"); root.AddReference(ReferenceTypes.Organizes, true, ObjectIds.ObjectsFolder); references.Add(new NodeStateReference(ReferenceTypes.Organizes, false, root.NodeId)); root.EventNotifier = EventNotifiers.SubscribeToEvents; List <BaseDataVariableState> variables = new List <BaseDataVariableState>(); try { #region Scalar FolderState scalarFolder = CreateFolder(root, "Scalar", "Scalar"); BaseDataVariableState scalarInstructions = CreateVariable(scalarFolder, "Scalar_Instructions", "Scalar_Instructions", DataTypeIds.String, ValueRanks.Scalar); scalarInstructions.Value = "A library of Read/Write Variables of all supported data-types."; variables.Add(scalarInstructions); #endregion #region Scalar_Static FolderState staticFolder = CreateFolder(root, "Scalar_Static", "Scalar_Static"); const string scalarStatic = "Scalar_Static_"; variables.Add(CreateVariable(staticFolder, scalarStatic + "Boolean", "Boolean", DataTypeIds.Boolean, ValueRanks.Scalar)); variables.Add(CreateVariable(staticFolder, scalarStatic + "Byte", "Byte", DataTypeIds.Byte, ValueRanks.Scalar)); variables.Add(CreateVariable(staticFolder, scalarStatic + "ByteString", "ByteString", DataTypeIds.ByteString, ValueRanks.Scalar)); variables.Add(CreateVariable(staticFolder, scalarStatic + "DateTime", "DateTime", DataTypeIds.DateTime, ValueRanks.Scalar)); variables.Add(CreateVariable(staticFolder, scalarStatic + "Double", "Double", DataTypeIds.Double, ValueRanks.Scalar)); BaseDataVariableState decimalVariable = CreateVariable(staticFolder, scalarStatic + "Decimal", "Decimal", DataTypeIds.DecimalDataType, ValueRanks.Scalar); // Set an arbitrary precision decimal value. BigInteger largeInteger = BigInteger.Parse("1234567890123546789012345678901234567890123456789012345"); DecimalDataType decimalValue = new DecimalDataType { Scale = 100, Value = largeInteger.ToByteArray() }; decimalVariable.Value = decimalValue; variables.Add(decimalVariable); #endregion #region Scalar_Simulation FolderState simulationFolder = CreateFolder(root, "Scalar_Smulation", "Simulation"); const string scalarSimulation = "Scalar_Simulation_"; CreateDynamicVariable(simulationFolder, scalarSimulation + "Boolean", "Boolean", DataTypeIds.Boolean, ValueRanks.Scalar); CreateDynamicVariable(simulationFolder, scalarSimulation + "Byte", "Byte", DataTypeIds.Byte, ValueRanks.Scalar); CreateDynamicVariable(simulationFolder, scalarSimulation + "ByteString", "ByteString", DataTypeIds.ByteString, ValueRanks.Scalar); CreateDynamicVariable(simulationFolder, scalarSimulation + "DateTime", "DateTime", DataTypeIds.DateTime, ValueRanks.Scalar); CreateDynamicVariable(simulationFolder, scalarSimulation + "Double", "Double", DataTypeIds.Double, ValueRanks.Scalar); CreateDynamicVariable(simulationFolder, scalarSimulation + "Duration", "Duration", DataTypeIds.Duration, ValueRanks.Scalar); BaseDataVariableState intervalVariable = CreateVariable(simulationFolder, scalarSimulation + "Interval", "Interval", DataTypeIds.UInt16, ValueRanks.Scalar); intervalVariable.Value = m_simulationInterval; intervalVariable.OnSimpleWriteValue = OnWriteInterval; BaseDataVariableState enabledVariable = CreateVariable(simulationFolder, scalarSimulation + "Enabled", "Enabled", DataTypeIds.Boolean, ValueRanks.Scalar); enabledVariable.Value = m_simulationEnabled; enabledVariable.OnSimpleWriteValue = OnWriteEnabled; #endregion } catch (Exception e) { Utils.Trace(e, "Error creating the address space."); } AddPredefinedNode(SystemContext, root); m_simulationTimer = new Timer(DoSimulation, null, 3000, 1000); } }