public object GetValue(string name)
        {
            Log.Debug($"GetValue called on path {Path}");

            if (Path == null || !Path.Contains("."))
            {
                // If at the top, or at a server, the next part can't be a tag:
                string nextPath = (Path == null) ? name : $"{Path}.{name}";
                return(new OPCDataProvider {
                    Path = nextPath, Snapshot = this.Snapshot
                });
            }
            string[] pathSplit = Path.Split(new char[] { '.' }, 2); // {Server Name}.{remaining.tag.path}

            Folder folder = opcServerOrm.Fetch().Select(ext => ext.GetEntity()).FirstOrDefault(f => f.EntityName == pathSplit[0]) as Folder;

            if (folder == null)
            {
                throw new Exception($"Could not find server named {pathSplit[0]}");
            }

            string[]     eventIds      = FolderService.GetFolderEntities <OPCEvent>(folder.FolderID).Select(e => e.Id).ToArray();
            BaseTagValue mostRecentTag = null;

            IDictionary <string, BaseTagValue> sourceDict = ((Snapshot as IDictionary <string, BaseTagValue>) ?? OPCEngine.mostRecentValues);

            foreach (string eventId in eventIds)
            {
                string       key = $"{eventId}|{pathSplit[1]}.{name}";
                BaseTagValue tag;
                if (sourceDict.TryGetValue(key, out tag))
                {
                    if (mostRecentTag == null || mostRecentTag.TimeStamp < tag.TimeStamp)
                    {
                        mostRecentTag = tag;
                    }
                }
            }

            if (mostRecentTag != null)
            {
                return(TagValueUtils.GetObjectValueFromTag(mostRecentTag));
            }

            // No current value found, so check folders to see whether this is a folder or a tag:

            Folder tagDataFolder = folder.GetSubFolder().FirstOrDefault(x => x.EntityName == "Tag Data");

            if (tagDataFolder == null)
            {
                throw new Exception("Tag data folder not found");
            }

            string[] parts         = pathSplit[1].Split('.');
            Folder   currentFolder = tagDataFolder;

            for (int i = 0; i < parts.Length; ++i)
            { // descend for each part, arriving at the folder which should contain the named entity
                Folder nextFolder = currentFolder.GetSubFolder().FirstOrDefault(x => x.EntityName == parts[i]);
                if (nextFolder == null)
                {
                    throw new Exception($"Folder '{parts[i]}' not found in folder '{currentFolder?.EntityName}'.");
                }
                currentFolder = nextFolder;
            }

            Folder namedFolder = FolderService.GetFolderEntities <Folder>(currentFolder.FolderID).FirstOrDefault(x => x.EntityName == name);

            if (namedFolder != null)
            {
                return new OPCDataProvider {
                           Path = $"{this.Path}.{name}", Snapshot = this.Snapshot
                }
            }
            ;

            OPCTag namedTag = FolderService.GetFolderEntities <OPCTag>(currentFolder.FolderID).FirstOrDefault(x => x.EntityName == name);

            if (namedTag != null)
            {
                throw new Exception($"Tag '{name}' has no known value");
            }
            else
            {
                throw new Exception($"No tag or folder '{name}' found in '{currentFolder.EntityName}'");
            }
        }
Exemple #2
0
        private static void UpdateTagsInFolder(string folderId, string baseFolderId, string serverUrl, OpcNode[] opcNodes)
        {
            // get the set of tags + folders within this folder, so that missing ones can be removed:
            HashSet <string> oldTagNames    = new HashSet <string>(FolderService.GetFolderEntities <OPCTag>(folderId).Select(x => x.EntityName));
            HashSet <string> oldFolderNames = new HashSet <string>(FolderService.GetFolderEntities <Folder>(folderId).Select(x => x.EntityName));

            foreach (OpcNode node in opcNodes)
            {
                if (ArrayUtilities.IsEmpty(node.Children))
                { // create or update tag
                    oldTagNames.Remove(node.Name);
                    OPCTag tag = FolderService.GetFolderEntities <OPCTag>(folderId).FirstOrDefault(x => x.EntityName == node.Name)
                                 ?? new OPCTag();

                    tag.EntityName     = node.Name;
                    tag.EntityFolderID = folderId;
                    tag.Path           = node.FullPath;
                    tag.TypeName       = node.TypeName;
                    tag.ServerUrl      = serverUrl;
                    tag.Store();
                }
                else
                {
                    oldFolderNames.Remove(node.Name);
                    Folder sf = FolderService.GetFolderEntities <Folder>(folderId).FirstOrDefault(x => x.EntityName == node.Name);
                    if (sf == null)
                    {
                        new Folder
                        {
                            EntityName         = node.Name,
                            EntityFolderID     = folderId,
                            FolderBehaviorType = typeof(DefaultFolderBehavior).FullName
                        }.Store();

                        // create, then fetch to make sure id is present.
                        sf = FolderService.GetFolderEntities <Folder>(folderId).FirstOrDefault(x => x.EntityName == node.Name);
                        if (sf == null)
                        {
                            throw new Exception($"Folder {node.Name} could not be created in {folderId}.");
                        }
                    }
                    UpdateTagsInFolder(sf.FolderID, baseFolderId, serverUrl, node.Children);
                }
            }

            foreach (string removedTag in oldTagNames)
            {
                OPCTag tag = FolderService.GetFolderEntities <OPCTag>(folderId).FirstOrDefault(x => x.EntityName == removedTag);
                if (tag != null)
                { // delete tag & matching flow constant:
                    tag.Delete();
                    string flowConstantId = $"OPCTAG__{baseFolderId}__{tag.Path}";
                    new ORM <FlowConstant>().Delete(flowConstantId);
                }
            }
            foreach (string removedFolder in oldFolderNames)
            {
                Folder folder = FolderService.GetFolderEntities <Folder>(folderId).FirstOrDefault(x => x.EntityName == removedFolder);
                if (folder != null)
                {
                    folder.Delete();
                }
            }
        }