/// <summary> /// Create an alert if conditions are met. /// </summary> ContosoPerformanceStatus UpdateAlert( ContosoTopologyNode node, double value, DateTime time, ContosoPerformanceSetting setting, ContosoAlertCause causeMin = ContosoAlertCause.AlertCauseValueBelowMinimum, ContosoAlertCause causeMax = ContosoAlertCause.AlertCauseValueAboveMaximum) { if (value != 0 && value < setting.Minimum) { ContosoAlert alert = new ContosoAlert(causeMin, node.Key, time); node.AddAlert(alert); node.Status = ContosoPerformanceStatus.Poor; } else if (value != 0 && value > setting.Maximum) { ContosoAlert alert = new ContosoAlert(causeMax, node.Key, time); node.AddAlert(alert); node.Status = ContosoPerformanceStatus.Poor; } else { node.Status = ContosoPerformanceStatus.Good; } return(node.Status); }
/// <summary> /// Creates the info for alert actions, which is sent to the client. /// </summary> public List <ContosoAlertActionInfo> CreateAlertActionInfo(ContosoAlertCause alertCause, string subKey) { // Get the alert actions. List <ContosoAlertActionDefinition> alertActionDefinitions = GetAlertActions(alertCause, subKey); if (alertActionDefinitions == null) { return(null); } // Create the alert info list. long id = 0; return(alertActionDefinitions.Select(actionDefinition => new ContosoAlertActionInfo(id++, actionDefinition.Type, actionDefinition.Description)).ToList()); }
/// <summary> /// Initializes an alert object. /// </summary> public void Init(ContosoAlertCause alertCause, string key, string subKey, DateTime time) { if (string.IsNullOrEmpty(key)) { throw new ArgumentException("key must be non null and not empty.", nameof(key)); } if (subKey == "TopologyRoot") { throw new ArgumentException("subKey is not allowed to be 'TopologyRoot'.", nameof(subKey)); } if (string.IsNullOrEmpty(subKey)) { subKey = "null"; } _id = _nextId++; Cause = alertCause; Key = key; SubKey = subKey; Time = time; Status = ContosoAlertStatus.AlertStatusActive; }
/// <summary> /// Ctor of the alert object, when the alert source is a topology node. /// </summary> public ContosoAlert(ContosoAlertCause alertCause, string key, DateTime time) { Init(alertCause, key, "null", time); }
/// <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); }
/// <summary> /// Get the alert actions definitions for the given alert cause.. /// </summary> public List <ContosoAlertActionDefinition> GetAlertActions(ContosoAlertCause alertCause, string subKey) { List <ContosoAlertActionDefinition> alertActionDefinitions = null; // Handle topology nodes if no subKey (OPC UA nodeid) is given. if (string.IsNullOrEmpty(subKey) || subKey.Equals("null")) { // Choose actions. switch (alertCause) { case ContosoAlertCause.AlertCauseOeeOverallBelowMinimum: alertActionDefinitions = OeeOverallPerformanceSetting.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseOeeOverallAboveMaximum: alertActionDefinitions = OeeOverallPerformanceSetting.MaximumAlertActions; break; case ContosoAlertCause.AlertCauseOeeAvailabilityBelowMinimum: alertActionDefinitions = OeeAvailabilityPerformanceSetting.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseOeeAvailabilityAboveMaximum: alertActionDefinitions = OeeAvailabilityPerformanceSetting.MaximumAlertActions; break; case ContosoAlertCause.AlertCauseOeePerformanceBelowMinimum: alertActionDefinitions = OeePerformancePerformanceSetting.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseOeePerformanceAboveMaximum: alertActionDefinitions = OeePerformancePerformanceSetting.MaximumAlertActions; break; case ContosoAlertCause.AlertCauseOeeQualityBelowMinimum: alertActionDefinitions = OeeQualityPerformanceSetting.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseOeeQualityAboveMaximum: alertActionDefinitions = OeeQualityPerformanceSetting.MaximumAlertActions; break; case ContosoAlertCause.AlertCauseKpi1BelowMinimum: alertActionDefinitions = Kpi1PerformanceSetting.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseKpi1AboveMaximum: alertActionDefinitions = Kpi1PerformanceSetting.MaximumAlertActions; break; case ContosoAlertCause.AlertCauseKpi2BelowMinimum: alertActionDefinitions = Kpi2PerformanceSetting.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseKpi2AboveMaximum: alertActionDefinitions = Kpi2PerformanceSetting.MaximumAlertActions; break; } } else { Station station = this as Station; ContosoOpcUaNode opcUaNode = station.NodeList.Find(node => node.NodeId == subKey) as ContosoOpcUaNode; switch (alertCause) { case ContosoAlertCause.AlertCauseValueBelowMinimum: alertActionDefinitions = opcUaNode.MinimumAlertActions; break; case ContosoAlertCause.AlertCauseValueAboveMaximum: alertActionDefinitions = opcUaNode.MaximumAlertActions; break; } } return(alertActionDefinitions); }