/// <summary> /// Create alert information for the UX from the given alert. /// </summary> private ContosoAlertInfo CreateDashboardAlertInfo(ContosoAlert alert, long sameCauseAlertsCount, string nodeKey) { ContosoAlertInfo alertInfo = new ContosoAlertInfo(); ContosoTopologyNode topologyNode = TopologyTable[alert.Key] as ContosoTopologyNode; alertInfo.AlertId = alert.AlertId; alertInfo.CauseDescription = alert.GetAlertCauseDescription(); alertInfo.Cause = alert.Cause; alertInfo.Occurences = sameCauseAlertsCount; List <string> parentList = GetFullHierarchy(nodeKey); alertInfo.TopologyDetails = new string[ContosoAlertInfo.MaxTopologyDetailsCount]; int index = 0; if (parentList.Count == 1) { alertInfo.TopologyDetails[index] = topologyNode.Name; } else { parentList.Reverse(); parentList.RemoveAt(0); foreach (var parent in parentList) { ContosoTopologyNode parentNode = (ContosoTopologyNode)TopologyTable[parent]; alertInfo.TopologyDetails[index++] = parentNode.Name; } // Check if the alert has been caused by an OPC UA node value. if (alert.SubKey != "null") { OpcUaNode opcUaNode = ((Station)TopologyTable[alert.Key]).GetOpcUaNode(alert.SubKey); alertInfo.TopologyDetails[index] = opcUaNode.SymbolicName; } } alertInfo.Key = alert.Key; alertInfo.SubKey = alert.SubKey; alertInfo.UxTime = string.Format("{0}-{1}", alert.Time.ToString("t"), alert.Time.ToString("d")); alertInfo.Time = alert.Time; alertInfo.Status = alert.Status; alertInfo.AlertActionInfo = topologyNode.CreateAlertActionInfo(alert.Cause, alert.SubKey); return(alertInfo); }
/// <summary> /// Create alert information for the UX from the given alert. /// </summary> private ContosoAlertInfo CreateDashboardAlertInfo(ContosoAlert alert, long sameCauseAlertsCount, string nodeKey) { ContosoAlertInfo alertInfo = new ContosoAlertInfo(); ContosoTopologyNode topologyNode = TopologyTable[alert.Key] as ContosoTopologyNode; alertInfo.AlertId = alert.AlertId; alertInfo.Cause = alert.Cause; alertInfo.Occurences = sameCauseAlertsCount; List <string> parentList = GetFullHierarchy(nodeKey); alertInfo.TopologyDetails = new string[ContosoAlertInfo.MaxTopologyDetailsCount]; int index = 0; if (parentList.Count == 1) { alertInfo.TopologyDetails[index] = topologyNode.Name; } else { parentList.Reverse(); parentList.RemoveAt(0); foreach (var parent in parentList) { ContosoTopologyNode parentNode = (ContosoTopologyNode)TopologyTable[parent]; alertInfo.TopologyDetails[index++] = parentNode.Name; } // Check if the alert has been caused by an OPC UA node value. if (alert.SubKey != "null") { ContosoOpcUaNode contosoOpcUaNode = Startup.Topology.GetOpcUaNode(alert.Key, alert.SubKey); alertInfo.TopologyDetails[index] = contosoOpcUaNode.SymbolicName; alertInfo.Maximum = contosoOpcUaNode.Maximum; alertInfo.Minimum = contosoOpcUaNode.Minimum; } else { switch (alert.Cause) { case ContosoAlertCause.AlertCauseOeeOverallBelowMinimum: case ContosoAlertCause.AlertCauseOeeOverallAboveMaximum: alertInfo.Maximum = topologyNode.OeeOverallPerformanceSetting.Maximum; alertInfo.Minimum = topologyNode.OeeOverallPerformanceSetting.Minimum; break; case ContosoAlertCause.AlertCauseOeeAvailabilityBelowMinimum: case ContosoAlertCause.AlertCauseOeeAvailabilityAboveMaximum: alertInfo.Maximum = topologyNode.OeeAvailabilityPerformanceSetting.Maximum; alertInfo.Minimum = topologyNode.OeeAvailabilityPerformanceSetting.Minimum; break; case ContosoAlertCause.AlertCauseOeePerformanceBelowMinimum: case ContosoAlertCause.AlertCauseOeePerformanceAboveMaximum: alertInfo.Maximum = topologyNode.OeePerformancePerformanceSetting.Maximum; alertInfo.Minimum = topologyNode.OeePerformancePerformanceSetting.Minimum; break; case ContosoAlertCause.AlertCauseOeeQualityBelowMinimum: case ContosoAlertCause.AlertCauseOeeQualityAboveMaximum: alertInfo.Maximum = topologyNode.OeeQualityPerformanceSetting.Maximum; alertInfo.Minimum = topologyNode.OeeQualityPerformanceSetting.Minimum; break; case ContosoAlertCause.AlertCauseKpi1BelowMinimum: case ContosoAlertCause.AlertCauseKpi1AboveMaximum: alertInfo.Maximum = topologyNode.Kpi1PerformanceSetting.Maximum; alertInfo.Minimum = topologyNode.Kpi1PerformanceSetting.Minimum; break; case ContosoAlertCause.AlertCauseKpi2BelowMinimum: case ContosoAlertCause.AlertCauseKpi2AboveMaximum: alertInfo.Maximum = topologyNode.Kpi2PerformanceSetting.Maximum; alertInfo.Minimum = topologyNode.Kpi2PerformanceSetting.Minimum; break; } } } alertInfo.Key = alert.Key; alertInfo.SubKey = alert.SubKey; alertInfo.UxTime = string.Format("{0}-{1}", alert.Time.ToString("t"), alert.Time.ToString("d")); alertInfo.Time = alert.Time; alertInfo.Status = alert.Status; alertInfo.AlertActionInfo = topologyNode.CreateAlertActionInfo(alert.Cause, alert.SubKey); return(alertInfo); }
/// <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); }