Beispiel #1
0
 /// <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);
 }
Beispiel #2
0
        /// <summary>
        /// Lookup the alert with alertId.
        /// </summary>
        public ContosoAlert FindAlert(long alertId)
        {
            List <string> allTopologyNodeKeys = GetAllChildren(TopologyRoot.Key);

            allTopologyNodeKeys.Add(TopologyRoot.Key);
            foreach (var key in allTopologyNodeKeys)
            {
                ContosoTopologyNode topologyNode = TopologyTable[key] as ContosoTopologyNode;
                if (topologyNode == null)
                {
                    Trace.TraceError($"Can not find node with key '{key}' in the topology.");
                    return(null);
                }

                // Check the node for the alert id.
                ContosoAlert alert = topologyNode.FindAlert(alertId);

                // Return when found.
                if (alert != null)
                {
                    return(alert);
                }
            }

            Trace.TraceError($"Can not find alert with id  '{alertId}'.");
            return(null);
        }
 /// <summary>
 /// The alert is added to the alert list of this node.
 /// </summary>
 public void AddAlert(ContosoAlert alert)
 {
     lock (_alertsLock)
     {
         Alerts.Add(alert);
     }
 }
        /// <summary>
        /// The all alerts, which have the same cause and are older then the given one are deleted.
        /// </summary>
        public bool CloseAlert(long alertId)
        {
            lock (_alertsLock)
            {
                // Verify existence of the alertId.
                ContosoAlert alert = Alerts.Find(x => x.AlertId == alertId);
                if (alert == null)
                {
                    Trace.TraceError($"alertId '{alertId}' in node '{Key}' can not be found.");
                    return(false);
                }

                // Fail if the alert is not yet acknowledged.
                if (alert.Status != ContosoAlertStatus.AlertStatusAcknowledged)
                {
                    Trace.TraceError($"alert with alertId '{alertId}' in node '{Key}' can not be closed, since it is not acknowledged ('{alert.Status}')");
                    return(false);
                }

                // Close all older alerts.
                List <ContosoAlert> oldAlerts = Alerts.FindAll(x => (x.Time <= alert.Time && x.Cause == alert.Cause));
                foreach (var alertToRemove in oldAlerts)
                {
                    Alerts.RemoveAll(x => x == alertToRemove);
                }
            }
            return(true);
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
        /// <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);
        }