예제 #1
0
        /// <summary>
        /// Initializes an area from a directory.
        /// </summary>
        public AreaState(ISystemContext context, DirectoryInfo directoryInfo) : base(null)
        {
            directoryInfo.Refresh();

            string name = directoryInfo.Name;

            // need to read the correct casing from the file system.
            if (directoryInfo.Exists)
            {
                DirectoryInfo[] directories = directoryInfo.Parent.GetDirectories(name);

                if (directories != null && directories.Length > 0)
                {
                    name = directories[0].Name;
                }
            }

            // get the system to use.
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system != null)
            {
                this.NodeId     = system.CreateNodeIdFromDirectoryPath(ObjectTypes.AreaType, directoryInfo.FullName);
                this.BrowseName = new QualifiedName(name, system.NamespaceIndex);
                this.OnValidate = system.ValidateArea;
            }

            this.DisplayName      = new LocalizedText(name);
            this.EventNotifier    = EventNotifiers.None;
            this.TypeDefinitionId = GetDefaultTypeDefinitionId(context.NamespaceUris);
        }
예제 #2
0
        /// <summary>
        /// Initializes the node manager.
        /// </summary>
        public FileSystemNodeManager(Opc.Ua.Server.IServerInternal server, string systemRoot)
            :
            base(server)
        {
            List <string> namespaceUris = new List <string>();

            namespaceUris.Add(Namespaces.FileSystem);
            namespaceUris.Add(Namespaces.FileSystem + "/Instance");

            NamespaceUris = namespaceUris;

            m_cache = new NodeIdDictionary <NodeState>();

            // create the directory.
            string absolutePath = Utils.GetAbsoluteDirectoryPath(systemRoot, true, false, true);

            // create the system.
            m_system = new FileSystemMonitor(
                SystemContext,
                absolutePath,
                server.NamespaceUris.GetIndexOrAppend(namespaceUris[1]),
                Lock);

            // update the default context.
            SystemContext.SystemHandle = m_system;
        }
        /// <summary>
        /// Initializes the node manager.
        /// </summary>
        public FileSystemNodeManager(Opc.Ua.Server.IServerInternal server, string systemRoot)
        :
            base(server)
        {
            List<string> namespaceUris = new List<string>();
         
            namespaceUris.Add(Namespaces.FileSystem);
            namespaceUris.Add(Namespaces.FileSystem + "/Instance");
            
            NamespaceUris = namespaceUris;

            m_cache = new NodeIdDictionary<NodeState>();

            // create the directory.
            string absolutePath = Utils.GetAbsoluteDirectoryPath(systemRoot, true, false,  true);
            
            // create the system.
            m_system = new FileSystemMonitor(
                SystemContext,
                absolutePath, 
                server.NamespaceUris.GetIndexOrAppend(namespaceUris[1]),
                Lock);
            
            // update the default context.
            SystemContext.SystemHandle = m_system;
        }
예제 #4
0
        /// <summary>
        /// Returns a unique handle for the node.
        /// </summary>
        /// <remarks>
        /// This must efficiently determine whether the node belongs to the node manager. If it does belong to
        /// NodeManager it should return a handle that does not require the NodeId to be validated again when
        /// the handle is passed into other methods such as 'Read' or 'Write'.
        /// </remarks>
        protected override object GetManagerHandle(ISystemContext context, NodeId nodeId, IDictionary <NodeId, NodeState> cache)
        {
            lock (Lock)
            {
                if (!IsNodeIdInNamespace(nodeId))
                {
                    return(null);
                }

                // check for cached node.
                NodeState node = null;

                if (m_cache.TryGetValue(nodeId, out node))
                {
                    return(node);
                }

                // check for a dynamic node.
                object handle = FileSystemMonitor.CreateHandleFromNodeId(context, nodeId, cache);

                if (handle != null)
                {
                    return(handle);
                }

                // base class will look up predefined nodes.
                return(base.GetManagerHandle(context, nodeId, cache));
            }
        }
예제 #5
0
        /// <summary>
        /// Creates a new controller file.
        /// </summary>
        private ServiceResult OnCreateController(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            string name,
            ref NodeId nodeId)
        {
            nodeId = null;

            // get the system to use.
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system == null)
            {
                return(StatusCodes.BadOutOfService);
            }

            // get the current dierctory.
            DirectoryInfo directory = GetDirectory(context, this.NodeId);

            if (directory == null || !directory.Exists)
            {
                return(StatusCodes.BadOutOfService);
            }

            // build the file path.
            StringBuilder filePath = new StringBuilder();

            filePath.Append(directory.FullName);
            filePath.Append('\\');
            filePath.Append(name);
            filePath.Append(".csv");

            if (File.Exists(filePath.ToString()))
            {
                return(StatusCodes.BadNodeIdExists);
            }

            // write a dummy configuration file.
            try
            {
                using (StreamWriter writer = new StreamWriter(filePath.ToString()))
                {
                    writer.WriteLine("Temperature, Double, 15");
                    writer.WriteLine("TemperatureSetPoint, Double, 15");
                }
            }
            catch (Exception e)
            {
                return(new ServiceResult(e, StatusCodes.BadUnexpectedError));
            }

            // return the node id.
            nodeId = system.CreateNodeIdFromFilePath(ObjectTypes.ControllerType, filePath.ToString());

            return(ServiceResult.Good);
        }
예제 #6
0
        /// <summary>
        /// Returns the next child with the requested browse name.
        /// </summary>
        private IReference FindByBrowseName()
        {
            NodeState target = null;

            // check if match found previously.
            if (m_position == UInt32.MaxValue)
            {
                return(null);
            }

            // get the system to use.
            FileSystemMonitor system = SystemContext.SystemHandle as FileSystemMonitor;

            if (system == null)
            {
                return(null);
            }

            // browse name must be qualified by the correct namespace.
            if (system.NamespaceIndex != base.BrowseName.NamespaceIndex)
            {
                return(null);
            }

            // look for file.
            FileInfo[] files = m_area.GetFiles(Utils.Format("{0}.csv", base.BrowseName.Name));

            if (files != null && files.Length > 0)
            {
                target = new ControllerState(SystemContext, files[0]);
            }

            // look for directory
            if (target == null)
            {
                DirectoryInfo[] directories =
                    m_area.GetDirectories(base.BrowseName.Name, SearchOption.TopDirectoryOnly);

                if (directories == null || directories.Length <= 0)
                {
                    return(null);
                }

                target = new AreaState(SystemContext, directories[0]);
            }

            // match found.
            m_position = UInt32.MaxValue;

            // return the requested reference type.
            return(new NodeStateReference(ReferenceTypeIds.Organizes, false, target));
        }
예제 #7
0
        /// <summary>
        /// Returns the directory for the area.
        /// </summary>
        public static DirectoryInfo GetDirectory(ISystemContext context, NodeId areaId)
        {
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system == null)
            {
                return(null);
            }

            string directoryPath = system.ExtractPathFromNodeId(areaId);

            return(new DirectoryInfo(directoryPath));
        }
예제 #8
0
        /// <summary>
        /// Returns the file for the controller.
        /// </summary>
        public static FileInfo GetFile(ISystemContext context, NodeId controllerId)
        {
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system == null)
            {
                return(null);
            }

            string filePath = system.ExtractPathFromNodeId(controllerId);

            filePath += ".csv";
            return(new FileInfo(filePath));
        }
예제 #9
0
        /// <summary>
        /// Initializes a controller from a file.
        /// </summary>
        public ControllerState(ISystemContext context, FileInfo fileInfo) : base(null)
        {
            fileInfo.Refresh();

            // extract the display name from the original file path.
            string name = fileInfo.Name;

            // need to read the correct casing from the file system.
            if (fileInfo.Exists)
            {
                FileInfo[] files = fileInfo.Directory.GetFiles(name);

                if (files != null && files.Length > 0)
                {
                    name = files[0].Name;
                }
            }

            int index = name.LastIndexOf('.');

            if (index >= 0)
            {
                name = name.Substring(0, index);
            }

            // get the system to use.
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system != null)
            {
                this.NodeId     = system.CreateNodeIdFromFilePath(ObjectTypes.ControllerType, fileInfo.FullName);
                this.BrowseName = new QualifiedName(name, system.NamespaceIndex);
                this.OnValidate = system.ValidateController;
            }

            this.DisplayName      = new LocalizedText(name);
            this.EventNotifier    = EventNotifiers.None;
            this.TypeDefinitionId = GetDefaultTypeDefinitionId(context.NamespaceUris);
        }
예제 #10
0
        /// <summary>
        /// Creates the appropriate NodeState object from a NodeId.
        /// </summary>
        public static NodeState CreateHandleFromNodeId(
            ISystemContext context,
            NodeId nodeId,
            IDictionary <NodeId, NodeState> cache)
        {
            // get the system to use.
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system == null)
            {
                return(null);
            }

            // check for valid node id.
            if (nodeId == null || nodeId.NamespaceIndex != system.m_namespaceIndex || nodeId.IdType != IdType.String)
            {
                return(null);
            }

            // lookup in cache.
            NodeState state = null;

            if (cache != null)
            {
                if (cache.TryGetValue(nodeId, out state))
                {
                    return(state);
                }
            }

            string path     = (string)nodeId.Identifier;
            uint   baseline = (uint)Convert.ToUInt32('0');

            // parse the object type id.
            uint objectTypeId = 0;
            int  start        = 0;

            for (int ii = 0; ii < path.Length; ii++)
            {
                if (path[ii] == ':')
                {
                    start = ii + 1;
                    break;
                }

                if (!Char.IsDigit(path[ii]))
                {
                    return(null);
                }

                objectTypeId *= 10;
                objectTypeId += (uint)Convert.ToUInt32(path[ii]) - baseline;
            }

            string parentPath = path;
            NodeId parentId   = nodeId;

            // check if referencing a child of the object.
            int end = -1;

            if (start < path.Length)
            {
                end = path.IndexOf(':', start);

                if (end >= start)
                {
                    parentPath = path.Substring(0, end);
                    parentId   = new NodeId(parentPath, system.NamespaceIndex);
                }
            }

            // return cached value if available.
            if (cache != null)
            {
                if (!cache.TryGetValue(parentId, out state))
                {
                    state = null;
                }
            }

            // create the object instance.
            if (state == null)
            {
                switch (objectTypeId)
                {
                case ObjectTypes.AreaType:
                {
                    string directoryPath = system.ExtractPathFromNodeId(nodeId);
                    state = new AreaState(context, new DirectoryInfo(directoryPath));
                    break;
                }

                case ObjectTypes.ControllerType:
                {
                    string filePath = system.ExtractPathFromNodeId(nodeId);
                    filePath += ".csv";
                    state     = new ControllerState(context, new FileInfo(filePath));
                    break;
                }

                default:
                {
                    return(null);
                }
                }

                // update cache if provided.
                if (cache != null)
                {
                    cache[parentId] = state;
                }
            }

            // nothing more to do if referencing the root.
            if (end < 0)
            {
                return(state);
            }

            // create the child identified by the name in the node id.
            string childPath = path.Substring(end + 1);

            // extract path of children.
            List <string> childNames = new List <string>();

            int index = childPath.IndexOf(':');

            while (index > 0)
            {
                childNames.Add(childPath.Substring(0, index));
                childPath = childPath.Substring(index + 1);
                index     = childPath.IndexOf(':');
            }

            childNames.Add(childPath);

            NodeState         parent = state;
            BaseInstanceState child  = null;

            for (int ii = 0; ii < childNames.Count; ii++)
            {
                child = parent.CreateChild(
                    context,
                    new QualifiedName(childNames[ii], 0));

                if (child == null)
                {
                    return(null);
                }

                parent = child;

                if (ii == childNames.Count - 1)
                {
                    child.NodeId = nodeId;

                    if (state.ValidationRequired)
                    {
                        child.OnValidate = system.ValidateChild;
                    }

                    if (cache != null)
                    {
                        cache[nodeId] = child;
                    }
                }
            }

            return(child);
        }