コード例 #1
0
ファイル: Alarm.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Gets an operation description for an alarm.
        /// </summary>
        /// <param name="alarm">Alarm to derive description for.</param>
        /// <param name="tagName">Label of associated measurement.</param>
        /// <returns>Derived label.</returns>
        public static string GetOperationDescription(Alarm alarm, string tagName)
        {
            StringBuilder description;

            description = new StringBuilder(tagName);

            AlarmOperation operation = alarm.Operation.GetEnumValueOrDefault<AlarmOperation>(AlarmOperation.Equal);

            switch (operation)
            {
                case AlarmOperation.Equal:
                    description.Append(" = ");
                    break;

                case AlarmOperation.NotEqual:
                    description.Append(" != ");
                    break;

                case AlarmOperation.GreaterOrEqual:
                    description.Append(" >= ");
                    break;

                case AlarmOperation.LessOrEqual:
                    description.Append(" <= ");
                    break;

                case AlarmOperation.GreaterThan:
                    description.Append(" > ");
                    break;

                case AlarmOperation.LessThan:
                    description.Append(" < ");
                    break;

                case AlarmOperation.Flatline:
                    if ((object)alarm.Delay == null)
                        return string.Empty;

                    description.Append(" flat-lined for ");
                    description.Append(alarm.Delay);
                    description.Append(" seconds");
                    return description.ToString();

                default:
                    description.Append(operation.GetDescription());
                    break;
            }

            if (alarm.SetPoint.HasValue)
                description.Append(alarm.SetPoint);
            else
                description.Append("undefined");

            return description.ToString();
        }
コード例 #2
0
ファイル: AlarmMonitor.cs プロジェクト: rmc00/gsf
 // Creates a data model based "RaisedAlarm" from an alarm
 private RaisedAlarm CreateRaisedAlarm(Alarm alarm)
 {
     return new RaisedAlarm
     {
         ID = alarm.ID,
         Severity = (int)alarm.Severity,
         TimeRaised = ((DateTime)alarm.TimeRaised).ToString("MM/dd/yyyy HH:mm:ss.fff"),
         TagName = alarm.TagName,
         Description = alarm.Description
     };
 }
コード例 #3
0
ファイル: Alarm.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Saves <see cref="Alarm"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="alarm">Information about <see cref="Alarm"/>.</param>        
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, Alarm alarm)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string updateQuery;
                Alarm createdAlarm = alarm;
                string successMessage = "Alarm information saved successfully";
                object associatedMeasurementId = (alarm.AssociatedMeasurementID != null) ? database.Guid(alarm.AssociatedMeasurementID.Value) : DBNull.Value;

                AlarmMonitor monitor = AlarmMonitor.Default;

                if (alarm.SetPointEnabled && (object)alarm.SetPoint == null)
                    throw new InvalidOperationException($"Set Point is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Set Point.");

                if (alarm.ToleranceEnabled && (object)alarm.Tolerance == null)
                    throw new InvalidOperationException($"Tolerance is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Tolerance.");

                if (alarm.DelayEnabled && (object)alarm.Delay == null)
                    throw new InvalidOperationException($"Delay is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Delay.");

                if (alarm.HysteresisEnabled && (object)alarm.Hysteresis == null)
                    throw new InvalidOperationException($"Hysteresis is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Hysteresis.");

                if (alarm.ID == 0)
                {
                    string query = database.ParameterizedQueryString("INSERT INTO Alarm (NodeID, TagName, SignalID, AssociatedMeasurementID, Description, Severity, Operation, SetPoint, Tolerance, Delay, " +
                        "Hysteresis, LoadOrder, Enabled, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) Values ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16})",
                        "nodeID", "tagName", "signalId", "associatedMeasurementId", "description", "severity", "operation", "setPoint", "tolerance", "delay",
                        "hysteresis", "loadOrder", "enabled", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, (alarm.NodeID != Guid.Empty) ? database.Guid(alarm.NodeID) : database.CurrentNodeID(),
                        alarm.TagName.ToNotNull(), database.Guid(alarm.SignalID), associatedMeasurementId, alarm.Description.ToNotNull(), alarm.Severity, alarm.Operation, alarm.SetPoint.ToNotNull(),
                        alarm.Tolerance.ToNotNull(), alarm.Delay.ToNotNull(), alarm.Hysteresis.ToNotNull(), alarm.LoadOrder, database.Bool(alarm.Enabled), CommonFunctions.CurrentUser, database.UtcNow,
                        CommonFunctions.CurrentUser, database.UtcNow);

                    createdAlarm = GetAlarm(database, string.Format("WHERE TagName = '{0}'", alarm.TagName));
                }
                else
                {
                    string query = database.ParameterizedQueryString("UPDATE Alarm SET NodeID = {0}, TagName = {1}, SignalID = {2}, AssociatedMeasurementID = {3}, Description = {4}, Severity = {5}, " +
                        "Operation = {6}, SetPoint = {7}, Tolerance = {8}, Delay = {9}, Hysteresis = {10}, LoadOrder = {11}, Enabled = {12}, UpdatedBy = {13}, UpdatedOn = {14} WHERE ID = {15}",
                        "nodeID", "tagName", "signalId", "associatedMeasurementId", "description", "severity", "operation", "setPoint", "tolerance", "delay", "hysteresis",
                        "loadOrder", "enabled", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, (alarm.NodeID != Guid.Empty) ? database.Guid(alarm.NodeID) : database.CurrentNodeID(),
                        alarm.TagName, database.Guid(alarm.SignalID), associatedMeasurementId, alarm.Description.ToNotNull(), alarm.Severity, alarm.Operation,
                        alarm.SetPoint.ToNotNull(), alarm.Tolerance.ToNotNull(), alarm.Delay.ToNotNull(), alarm.Hysteresis.ToNotNull(), alarm.LoadOrder, database.Bool(alarm.Enabled),
                        CommonFunctions.CurrentUser, database.UtcNow, alarm.ID);
                }

                updateQuery = database.ParameterizedQueryString("UPDATE Alarm SET AssociatedMeasurementID = {0} WHERE ID = {1}", "associatedMeasurementId", "id");

                if (alarm.CreateAssociatedMeasurement && (object)alarm.AssociatedMeasurementID == null)
                {
                    alarm.AssociatedMeasurementID = CreateAlarmMeasurement(database, createdAlarm);

                    if ((object)alarm.AssociatedMeasurementID != null)
                        database.Connection.ExecuteNonQuery(updateQuery, DefaultTimeout, database.Guid(alarm.AssociatedMeasurementID.Value), createdAlarm.ID);
                    else
                        successMessage += " but failed to create associated measurement";
                }
                else if (!alarm.CreateAssociatedMeasurement && (object)alarm.AssociatedMeasurementID != null)
                {
                    database.Connection.ExecuteNonQuery(updateQuery, DefaultTimeout, DBNull.Value, createdAlarm.ID);
                    DeleteAlarmMeasurement(database, createdAlarm.AssociatedMeasurementID.Value);
                    alarm.AssociatedMeasurementID = null;
                }

                if ((object)monitor != null)
                    monitor.UpdateDefinedAlarms();

                try
                {
                    CommonFunctions.SendCommandToService("ReloadConfig");
                }
                catch (Exception ex)
                {
                    CommonFunctions.LogException(database, "Alarm Save", ex);
                }

                return successMessage;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #4
0
ファイル: Alarm.cs プロジェクト: rmc00/gsf
        // Creates a measurement associated with the given alarm and returns the new measurements signal ID.
        private static Guid? CreateAlarmMeasurement(AdoDataConnection database, Alarm alarm)
        {
            object nodeID;
            Historian historian;
            Measurement alarmMeasurement;
            int signalTypeId;

            try
            {
                nodeID = (alarm.NodeID != Guid.Empty) ? database.Guid(alarm.NodeID) : database.CurrentNodeID();
                historian = Historian.GetHistorian(database, string.Format("WHERE Acronym = 'STAT' AND NodeID = '{0}'", nodeID));
                signalTypeId = Convert.ToInt32(database.Connection.ExecuteScalar("SELECT ID FROM SignalType WHERE Acronym = 'ALRM'", DefaultTimeout));

                alarmMeasurement = new Measurement()
                {
                    HistorianID = historian.ID,
                    PointTag = alarm.TagName,
                    SignalTypeID = signalTypeId,
                    SignalReference = "ALARM!SERVICES-AL" + alarm.ID,
                    Description = "Measurement associated with alarm " + alarm.ID,
                    Internal = true,
                    Enabled = true
                };

                Measurement.Save(database, alarmMeasurement);
                alarmMeasurement = Measurement.GetMeasurement(database, string.Format("WHERE PointTag = '{0}'", alarm.TagName));

                return alarmMeasurement.SignalID;
            }
            catch
            {
                // Return null to indicate measurement
                // was not saved to database
                return null;
            }
        }
コード例 #5
0
ファイル: Alarm.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Retrieves an <see cref="Alarm"/> information from the database based on query string filter.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="whereClause">Filter clause to append to the SELECT query.</param>
        /// <returns><see cref="Alarm"/> information.</returns>
        public static Alarm GetAlarm(AdoDataConnection database, string whereClause)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                DataTable alarmTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Alarm " + whereClause);

                if (alarmTable.Rows.Count == 0)
                    return null;

                DataRow row = alarmTable.Rows[0];
                object associatedMeasurementId = row.Field<object>("AssociatedMeasurementID");

                Alarm alarm = new Alarm
                {
                    NodeID = database.Guid(row, "NodeID"),
                    ID = row.ConvertField<int>("ID"),
                    TagName = row.Field<string>("TagName"),
                    SignalID = database.Guid(row, "SignalID"),
                    AssociatedMeasurementID = ((object)associatedMeasurementId != null) ? Guid.Parse(associatedMeasurementId.ToString()) : (Guid?)null,
                    Description = row.Field<string>("Description"),
                    Severity = row.ConvertField<int>("Severity"),
                    Operation = row.ConvertField<int>("Operation"),
                    SetPoint = row.ConvertNullableField<double>("SetPoint"),
                    Tolerance = row.ConvertNullableField<double>("Tolerance"),
                    Delay = row.ConvertNullableField<double>("Delay"),
                    Hysteresis = row.ConvertNullableField<double>("Hysteresis"),
                    LoadOrder = row.ConvertField<int>("LoadOrder"),
                    Enabled = row.ConvertField<bool>("Enabled")
                };

                return alarm;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #6
0
ファイル: Alarm.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Loads <see cref="Alarm"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>        
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the adapters to be loaded from the database.</param>
        /// <returns>Collection of <see cref="Alarm"/>.</returns>
        public static ObservableCollection<Alarm> Load(AdoDataConnection database, IList<int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                Alarm[] alarmList = null;
                DataTable alarmTable;
                object associatedMeasurementId;
                int id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = database.ParameterizedQueryString(string.Format("SELECT NodeID, TagName, ID, SignalID, AssociatedMeasurementID, Description, Severity, Operation, " +
                        "SetPoint, Tolerance, Delay, Hysteresis, LoadOrder, Enabled FROM Alarm WHERE NodeID = {{0}} AND ID IN ({0})", commaSeparatedKeys), "nodeID");

                    alarmTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID());
                    alarmList = new Alarm[alarmTable.Rows.Count];

                    foreach (DataRow row in alarmTable.Rows)
                    {
                        id = row.ConvertField<int>("ID");
                        associatedMeasurementId = row.Field<object>("AssociatedMeasurementID");

                        alarmList[keys.IndexOf(id)] = new Alarm()
                        {
                            NodeID = database.Guid(row, "NodeID"),
                            ID = id,
                            TagName = row.Field<string>("TagName"),
                            SignalID = database.Guid(row, "SignalID"),
                            AssociatedMeasurementID = (associatedMeasurementId != null) ? Guid.Parse(associatedMeasurementId.ToString()) : (Guid?)null,
                            Description = row.Field<string>("Description"),
                            Severity = row.ConvertField<int>("Severity"),
                            Operation = row.ConvertField<int>("Operation"),
                            SetPoint = row.ConvertNullableField<double>("SetPoint"),
                            Tolerance = row.ConvertNullableField<double>("Tolerance"),
                            Delay = row.ConvertNullableField<double>("Delay"),
                            Hysteresis = row.ConvertNullableField<double>("Hysteresis"),
                            LoadOrder = row.ConvertField<int>("LoadOrder"),
                            Enabled = row.ConvertField<bool>("Enabled"),
                            CreateAssociatedMeasurement = (associatedMeasurementId != null)
                        };
                    }
                }

                return new ObservableCollection<Alarm>(alarmList ?? new Alarm[0]);
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #7
0
ファイル: Alarm.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Gets an operation description for an alarm.
        /// </summary>
        /// <param name="alarm">Alarm to derive description for.</param>
        /// <param name="tagName">Label of associated measurement.</param>
        /// <returns>Derived label.</returns>
        public static string GetOperationDescription(Alarm alarm, string tagName)
        {
            StringBuilder description;

            description = new StringBuilder(tagName);

            AlarmOperation operation = alarm.Operation.GetEnumValueOrDefault <AlarmOperation>(AlarmOperation.Equal);

            switch (operation)
            {
            case AlarmOperation.Equal:
                description.Append(" = ");
                break;

            case AlarmOperation.NotEqual:
                description.Append(" != ");
                break;

            case AlarmOperation.GreaterOrEqual:
                description.Append(" >= ");
                break;

            case AlarmOperation.LessOrEqual:
                description.Append(" <= ");
                break;

            case AlarmOperation.GreaterThan:
                description.Append(" > ");
                break;

            case AlarmOperation.LessThan:
                description.Append(" < ");
                break;

            case AlarmOperation.Flatline:
                if ((object)alarm.Delay == null)
                {
                    return(string.Empty);
                }

                description.Append(" flat-lined for ");
                description.Append(alarm.Delay);
                description.Append(" seconds");
                return(description.ToString());

            default:
                description.Append(operation.GetDescription());
                break;
            }

            if (alarm.SetPoint.HasValue)
            {
                description.Append(alarm.SetPoint);
            }
            else
            {
                description.Append("undefined");
            }

            return(description.ToString());
        }
コード例 #8
0
ファイル: Alarm.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Saves <see cref="Alarm"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="alarm">Information about <see cref="Alarm"/>.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, Alarm alarm)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string updateQuery;
                Alarm  createdAlarm            = alarm;
                string successMessage          = "Alarm information saved successfully";
                object associatedMeasurementId = (alarm.AssociatedMeasurementID != null) ? database.Guid(alarm.AssociatedMeasurementID.Value) : DBNull.Value;

                AlarmMonitor monitor = AlarmMonitor.Default;

                if (alarm.SetPointEnabled && (object)alarm.SetPoint == null)
                {
                    throw new InvalidOperationException($"Set Point is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Set Point.");
                }

                if (alarm.ToleranceEnabled && (object)alarm.Tolerance == null)
                {
                    throw new InvalidOperationException($"Tolerance is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Tolerance.");
                }

                if (alarm.DelayEnabled && (object)alarm.Delay == null)
                {
                    throw new InvalidOperationException($"Delay is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Delay.");
                }

                if (alarm.HysteresisEnabled && (object)alarm.Hysteresis == null)
                {
                    throw new InvalidOperationException($"Hysteresis is required for alarms of type \"{((AlarmOperation)alarm.Operation).GetDescription()}\". Please define a Hysteresis.");
                }

                if (alarm.ID == 0)
                {
                    string query = database.ParameterizedQueryString("INSERT INTO Alarm (NodeID, TagName, SignalID, AssociatedMeasurementID, Description, Severity, Operation, SetPoint, Tolerance, Delay, " +
                                                                     "Hysteresis, LoadOrder, Enabled, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) Values ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16})",
                                                                     "nodeID", "tagName", "signalId", "associatedMeasurementId", "description", "severity", "operation", "setPoint", "tolerance", "delay",
                                                                     "hysteresis", "loadOrder", "enabled", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, (alarm.NodeID != Guid.Empty) ? database.Guid(alarm.NodeID) : database.CurrentNodeID(),
                                                        alarm.TagName.ToNotNull(), database.Guid(alarm.SignalID), associatedMeasurementId, alarm.Description.ToNotNull(), alarm.Severity, alarm.Operation, alarm.SetPoint.ToNotNull(),
                                                        alarm.Tolerance.ToNotNull(), alarm.Delay.ToNotNull(), alarm.Hysteresis.ToNotNull(), alarm.LoadOrder, database.Bool(alarm.Enabled), CommonFunctions.CurrentUser, database.UtcNow,
                                                        CommonFunctions.CurrentUser, database.UtcNow);

                    createdAlarm = GetAlarm(database, string.Format("WHERE TagName = '{0}'", alarm.TagName));
                }
                else
                {
                    string query = database.ParameterizedQueryString("UPDATE Alarm SET NodeID = {0}, TagName = {1}, SignalID = {2}, AssociatedMeasurementID = {3}, Description = {4}, Severity = {5}, " +
                                                                     "Operation = {6}, SetPoint = {7}, Tolerance = {8}, Delay = {9}, Hysteresis = {10}, LoadOrder = {11}, Enabled = {12}, UpdatedBy = {13}, UpdatedOn = {14} WHERE ID = {15}",
                                                                     "nodeID", "tagName", "signalId", "associatedMeasurementId", "description", "severity", "operation", "setPoint", "tolerance", "delay", "hysteresis",
                                                                     "loadOrder", "enabled", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, (alarm.NodeID != Guid.Empty) ? database.Guid(alarm.NodeID) : database.CurrentNodeID(),
                                                        alarm.TagName, database.Guid(alarm.SignalID), associatedMeasurementId, alarm.Description.ToNotNull(), alarm.Severity, alarm.Operation,
                                                        alarm.SetPoint.ToNotNull(), alarm.Tolerance.ToNotNull(), alarm.Delay.ToNotNull(), alarm.Hysteresis.ToNotNull(), alarm.LoadOrder, database.Bool(alarm.Enabled),
                                                        CommonFunctions.CurrentUser, database.UtcNow, alarm.ID);
                }

                updateQuery = database.ParameterizedQueryString("UPDATE Alarm SET AssociatedMeasurementID = {0} WHERE ID = {1}", "associatedMeasurementId", "id");

                if (alarm.CreateAssociatedMeasurement && (object)alarm.AssociatedMeasurementID == null)
                {
                    alarm.AssociatedMeasurementID = CreateAlarmMeasurement(database, createdAlarm);

                    if ((object)alarm.AssociatedMeasurementID != null)
                    {
                        database.Connection.ExecuteNonQuery(updateQuery, DefaultTimeout, database.Guid(alarm.AssociatedMeasurementID.Value), createdAlarm.ID);
                    }
                    else
                    {
                        successMessage += " but failed to create associated measurement";
                    }
                }
                else if (!alarm.CreateAssociatedMeasurement && (object)alarm.AssociatedMeasurementID != null)
                {
                    database.Connection.ExecuteNonQuery(updateQuery, DefaultTimeout, DBNull.Value, createdAlarm.ID);
                    DeleteAlarmMeasurement(database, createdAlarm.AssociatedMeasurementID.Value);
                    alarm.AssociatedMeasurementID = null;
                }

                if ((object)monitor != null)
                {
                    monitor.UpdateDefinedAlarms();
                }

                try
                {
                    CommonFunctions.SendCommandToService("ReloadConfig");
                }
                catch (Exception ex)
                {
                    CommonFunctions.LogException(database, "Alarm Save", ex);
                }

                return(successMessage);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #9
0
ファイル: Alarm.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Loads <see cref="Alarm"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the adapters to be loaded from the database.</param>
        /// <returns>Collection of <see cref="Alarm"/>.</returns>
        public static ObservableCollection <Alarm> Load(AdoDataConnection database, IList <int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                Alarm[]   alarmList = null;
                DataTable alarmTable;
                object    associatedMeasurementId;
                int       id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = database.ParameterizedQueryString(string.Format("SELECT NodeID, TagName, ID, SignalID, AssociatedMeasurementID, Description, Severity, Operation, " +
                                                                            "SetPoint, Tolerance, Delay, Hysteresis, LoadOrder, Enabled FROM Alarm WHERE NodeID = {{0}} AND ID IN ({0})", commaSeparatedKeys), "nodeID");

                    alarmTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID());
                    alarmList  = new Alarm[alarmTable.Rows.Count];

                    foreach (DataRow row in alarmTable.Rows)
                    {
                        id = row.ConvertField <int>("ID");
                        associatedMeasurementId = row.Field <object>("AssociatedMeasurementID");

                        alarmList[keys.IndexOf(id)] = new Alarm()
                        {
                            NodeID   = database.Guid(row, "NodeID"),
                            ID       = id,
                            TagName  = row.Field <string>("TagName"),
                            SignalID = database.Guid(row, "SignalID"),
                            AssociatedMeasurementID = (associatedMeasurementId != null) ? Guid.Parse(associatedMeasurementId.ToString()) : (Guid?)null,
                            Description             = row.Field <string>("Description"),
                            Severity   = row.ConvertField <int>("Severity"),
                            Operation  = row.ConvertField <int>("Operation"),
                            SetPoint   = row.ConvertNullableField <double>("SetPoint"),
                            Tolerance  = row.ConvertNullableField <double>("Tolerance"),
                            Delay      = row.ConvertNullableField <double>("Delay"),
                            Hysteresis = row.ConvertNullableField <double>("Hysteresis"),
                            LoadOrder  = row.ConvertField <int>("LoadOrder"),
                            Enabled    = row.ConvertField <bool>("Enabled"),
                            CreateAssociatedMeasurement = (associatedMeasurementId != null)
                        };
                    }
                }

                return(new ObservableCollection <Alarm>(alarmList ?? new Alarm[0]));
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }