/// <summary> /// Initializes a new instance of the <see cref="BlockState"/> class. /// </summary> /// <param name="nodeManager">The context.</param> /// <param name="nodeId">The node id.</param> /// <param name="block">The block.</param> public BlockState( DataAccessNodeManager nodeManager, NodeId nodeId, UnderlyingSystemBlock block) : base(null) { _blockId = block.Id; _nodeManager = nodeManager; SymbolicName = block.Name; NodeId = nodeId; BrowseName = new QualifiedName(block.Name, nodeId.NamespaceIndex); DisplayName = new LocalizedText(block.Name); Description = null; WriteMask = 0; UserWriteMask = 0; EventNotifier = EventNotifiers.None; if (nodeManager.SystemContext.SystemHandle is UnderlyingSystem system) { var tags = block.GetTags(); for (var ii = 0; ii < tags.Count; ii++) { var variable = CreateVariable(nodeManager.SystemContext, tags[ii]); AddChild(variable); variable.OnSimpleWriteValue = OnWriteTagValue; } } }
/// <summary> /// Finds a block. /// </summary> /// <param name="blockId">The block identifier.</param> /// <returns>The block.</returns> public UnderlyingSystemBlock FindBlock(string blockId) { UnderlyingSystemBlock block = null; lock (_lock) { // check for invalid name. if (string.IsNullOrEmpty(blockId)) { return(null); } // look for cached block. if (_blocks.TryGetValue(blockId, out block)) { return(block); } // lookup block in database. string blockType = null; var length = blockId.Length; for (var ii = 0; ii < s_BlockDatabase.Length; ii++) { blockType = s_BlockDatabase[ii]; if (length >= blockType.Length || blockType[length] != '/') { continue; } if (blockType.StartsWith(blockId, StringComparison.Ordinal)) { blockType = blockType.Substring(length + 1); break; } blockType = null; } // block not found. if (blockType == null) { return(null); } // create a new block. block = new UnderlyingSystemBlock { // create the block. Id = blockId, Name = blockId, BlockType = blockType }; _blocks.Add(blockId, block); // add the tags based on the block type. // note that the block and tag types used here are types defined by the underlying system. // the node manager will need to map these types to UA defined types. switch (block.BlockType) { case "FlowSensor": { block.CreateTag("Measurement", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Analog, "liters/sec", false); block.CreateTag("Online", UnderlyingSystemDataType.Integer1, UnderlyingSystemTagType.Digital, null, false); break; } case "LevelSensor": { block.CreateTag("Measurement", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Analog, "liters", false); block.CreateTag("Online", UnderlyingSystemDataType.Integer1, UnderlyingSystemTagType.Digital, null, false); break; } case "Controller": { block.CreateTag("SetPoint", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, true); block.CreateTag("Measurement", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, false); block.CreateTag("Output", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, false); block.CreateTag("Status", UnderlyingSystemDataType.Integer4, UnderlyingSystemTagType.Enumerated, null, false); break; } case "CustomController": { block.CreateTag("Input1", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, true); block.CreateTag("Input2", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, true); block.CreateTag("Input3", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, true); block.CreateTag("Output", UnderlyingSystemDataType.Real4, UnderlyingSystemTagType.Normal, null, false); break; } } } // return the new block. return(block); }