/// <summary> /// Returns a list of all nodes under the given node, with the given type and name. /// </summary> /// <returns> public List <string> GetAllChildren(string key, Type type, string name) { List <string> allChildren = new List <string>(); foreach (var child in ((TopologyNode)TopologyTable[key]).GetChildren()) { ContosoTopologyNode node = TopologyTable[child] as ContosoTopologyNode; if (node != null) { if (node.GetType() == type && node.Name == name) { allChildren.Add(child); } if (((TopologyNode)TopologyTable[child]).ChildrenCount > 0) { allChildren.AddRange(GetAllChildren(child, type, name)); } } } return(allChildren); }
/// <summary> /// Returns information for all children of the given topology node. /// This information will be shown in the UX. /// </summary> /// <param name="parentKey"></param> public List <ContosoChildInfo> GetChildrenInfo(string parentKey) { List <ContosoChildInfo> childrenInfo = new List <ContosoChildInfo>(); // Update type of children for the given key. ContosoTopologyNode parent = (ContosoTopologyNode)TopologyTable[parentKey]; Type childrenType = null; Type parentType = parent.GetType(); childrenType = typeof(Factory); if (parentType == typeof(Factory)) { childrenType = typeof(ProductionLine); } else if (parentType == typeof(ProductionLine)) { childrenType = typeof(Station); } else if (parentType == typeof(Station)) { childrenType = typeof(ContosoOpcUaNode); } // Prepare the list with the child objects for the view. if (childrenType == typeof(ContosoOpcUaNode)) { Station station = (Station)TopologyTable[parentKey]; foreach (ContosoOpcUaNode opcUaNode in station.NodeList) { ContosoChildInfo childInfo = new ContosoChildInfo(station.Key, opcUaNode.NodeId, opcUaNode.Status.ToString(), opcUaNode.SymbolicName, opcUaNode.SymbolicName, station.Location.City, station.Location.Latitude, station.Location.Longitude, opcUaNode.Visible, opcUaNode.LastValueToUxString(), opcUaNode.Units, opcUaNode.ImagePushpin); childrenInfo.Add(childInfo); } } else { var childrenKeys = ((ContosoTopologyNode)TopologyTable[parentKey]).GetChildren(); foreach (string key in childrenKeys) { if (childrenType == typeof(Factory)) { Factory factory = (Factory)TopologyTable[key]; ContosoChildInfo dashboardChild = new ContosoChildInfo(factory.Key, factory.Status.ToString(), factory.Name, factory.Description, factory.Location.City, factory.Location.Latitude, factory.Location.Longitude, true, factory.ImagePushpin); childrenInfo.Add(dashboardChild); } if (childrenType == typeof(ProductionLine)) { ProductionLine productionLine = (ProductionLine)TopologyTable[key]; ContosoChildInfo dashboardChild = new ContosoChildInfo(productionLine.Key, productionLine.Status.ToString(), productionLine.Name, productionLine.Description, productionLine.Location.City, productionLine.Location.Latitude, productionLine.Location.Longitude, true, productionLine.ImagePushpin); childrenInfo.Add(dashboardChild); } if (childrenType == typeof(Station)) { Station station = (Station)TopologyTable[key]; ContosoChildInfo dashboardChild = new ContosoChildInfo(station.Key, station.Status.ToString(), station.Name, station.Description, station.Location.City, station.Location.Latitude, station.Location.Longitude, true, station.ImagePushpin); childrenInfo.Add(dashboardChild); } } } return(childrenInfo); }
/// <summary> /// Gets alert information for the given topology node and all nodes below it. /// Multiple alerts with the same cause are consolidated and only the time information for the newest alert is returned. /// This information will be shown in the UX. /// </summary> public List <ContosoAlertInfo> GetAlerts(string key) { List <ContosoAlert> alertList = GetAllAlerts(key); List <ContosoAlertInfo> dashboardAlerts = new List <ContosoAlertInfo>(); ContosoAlertCause dummyAlertCause = new ContosoAlertCause(); ContosoAlertInfo dashboardAlert = new ContosoAlertInfo(); if (alertList.Count == 0) { return(dashboardAlerts); } List <string> allNodeKey = GetAllChildren(key); // Add key itself as well. allNodeKey.Add(key); foreach (var nodeKey in allNodeKey) { ContosoTopologyNode topologyNode = TopologyTable[nodeKey] as ContosoTopologyNode; List <ContosoAlert> childAlerts = topologyNode.Alerts; if (childAlerts.Count > 0) { if (topologyNode.GetType() == typeof(Station)) { Station station = topologyNode as Station; // The OPC UA nodes only generate value alerts. foreach (var opcNode in station.NodeList) { foreach (ContosoAlertCause alertCause in Enum.GetValues(dummyAlertCause.GetType())) { if (alertCause == ContosoAlertCause.AlertCauseValueBelowMinimum || alertCause == ContosoAlertCause.AlertCauseValueAboveMaximum) { // Aggregate similar alerts. List <ContosoAlert> sameCauseAlerts = childAlerts.FindAll(x => (x.Cause == alertCause && x.Key == nodeKey && x.SubKey == opcNode.NodeId && x.Time != DateTime.MinValue)); if (sameCauseAlerts.Count > 0) { // Find the newest alert. long newestTicks = sameCauseAlerts.Max(x => x.Time.Ticks); ContosoAlert alert = sameCauseAlerts.Find(x => x.Time.Ticks == newestTicks); // Create alert dashboard info and add it to the dashboard alert list. dashboardAlert = CreateDashboardAlertInfo(alert, sameCauseAlerts.Count, nodeKey); dashboardAlerts.Add(dashboardAlert); } } } } // For the station node we handle performance alerts. foreach (ContosoAlertCause alertCause in Enum.GetValues(dummyAlertCause.GetType())) { if (alertCause == ContosoAlertCause.AlertCauseValueBelowMinimum || alertCause == ContosoAlertCause.AlertCauseValueAboveMaximum) { continue; } // Aggregate similar alerts. List <ContosoAlert> sameCauseAlerts = childAlerts.FindAll(x => (x.Cause == alertCause && x.Key == nodeKey && x.Time != DateTime.MinValue)); if (sameCauseAlerts.Count > 0) { // Find the newest alert. long newestTicks = sameCauseAlerts.Max(x => x.Time.Ticks); ContosoAlert alert = sameCauseAlerts.Find(x => x.Time.Ticks == newestTicks); // Create alert dashboard info and add it to the dashboard alert list. dashboardAlert = CreateDashboardAlertInfo(alert, sameCauseAlerts.Count, nodeKey); dashboardAlerts.Add(dashboardAlert); } } } else { foreach (ContosoAlertCause alertCause in Enum.GetValues(dummyAlertCause.GetType())) { // Aggregate similar alerts. List <ContosoAlert> sameCauseAlerts = childAlerts.FindAll(x => (x.Cause == alertCause && x.Key == nodeKey && x.Time != DateTime.MinValue)); if (sameCauseAlerts.Count > 0) { // Find the newest alert. long newestTicks = sameCauseAlerts.Max(x => x.Time.Ticks); ContosoAlert alert = sameCauseAlerts.Find(x => x.Time.Ticks == newestTicks); // Create alert dashboard info and add it to the dashboard alert list. dashboardAlert = CreateDashboardAlertInfo(alert, sameCauseAlerts.Count, nodeKey); dashboardAlerts.Add(dashboardAlert); } } } } } dashboardAlerts.Sort(delegate(ContosoAlertInfo x, ContosoAlertInfo y) { if (x.Time < y.Time) { return(1); } if (x.Time == y.Time) { return(0); } return(-1); }); return(dashboardAlerts); }