/// <summary> /// Creates an instance of <see cref="InputWizardUserControl"/> class for the specified <see cref="Device"/>. /// </summary> /// <param name="device"></param> public InputWizardUserControl(Device device) : this() { if (device != null) { m_dataContext.SkipDisableRealTimeData = device.SkipDisableRealTimeData; m_dataContext.ConnectionString = device.ConnectionString; m_dataContext.AlternateCommandChannel = device.AlternateCommandChannel; m_dataContext.AccessID = device.AccessID; m_dataContext.ProtocolID = device.ProtocolID ?? 0; m_dataContext.CompanyID = device.CompanyID ?? 0; m_dataContext.HistorianID = device.HistorianID ?? 0; m_dataContext.InterconnectionID = device.InterconnectionID ?? 0; if (device.IsConcentrator) { m_dataContext.ConnectToConcentrator = true; m_dataContext.PdcAcronym = device.Acronym; m_dataContext.PdcName = device.Name; m_dataContext.PdcVendorDeviceID = device.VendorDeviceID ?? 0; } m_dataContext.StepTwoExpanded = true; m_dataContext.CurrentDeviceRuntimeID = Convert.ToInt32(CommonFunctions.GetRuntimeID("Device", device.ID)); m_dataContext.NewDeviceConfiguration = false; } }
/// <summary> /// Creates an instance of <see cref="DeviceUserControl"/> class. /// </summary> /// <param name="device"><see cref="Device"/> to be edited.</param> public DeviceUserControl(Device device) { InitializeComponent(); Loaded += DeviceUserControl_Loaded; Unloaded += DeviceUserControl_Unloaded; if ((object)device == null) DataContext = new Devices(0, false); else DataContext = new Devices(0, false, device); }
private static string BuildConnectionString(Device device) { if (device.ConnectionString == null) return string.Empty; string connectionString = device.ConnectionString; if (!string.IsNullOrEmpty(device.AlternateCommandChannel)) { if (!connectionString.EndsWith(";")) connectionString += ";"; connectionString += "commandchannel={" + device.AlternateCommandChannel + "}"; } return connectionString; }
/// <summary> /// Sends required commands to backend service to notify that <see cref="Device"/> configuration has changed. /// </summary> /// <param name="device"><see cref="Device"/> whose configuration has changed.</param> /// <param name="historianID">ID of the historian to refresh metadata if device is null.</param> public static void NotifyService(Device device, int? historianID = null) { if ((object)device != null) { if (device.Enabled) { if (device.ParentID == null) CommonFunctions.SendCommandToService("Initialize " + CommonFunctions.GetRuntimeID("Device", device.ID)); else CommonFunctions.SendCommandToService("Initialize " + CommonFunctions.GetRuntimeID("Device", (int)device.ParentID)); } else { // We do this to make sure all statistical measurements are in the system. CommonFunctions.SendCommandToService("ReloadConfig"); } } else { CommonFunctions.SendCommandToService("ReloadConfig"); } }
/// <summary> /// Retrieve a <see cref="Device"/> information from the database based on query string filter. /// </summary> /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param> /// <param name="whereClause">query string to filter data.</param> /// <returns><see cref="Device"/> information.</returns> public static Device GetDevice(AdoDataConnection database, string whereClause) { bool createdConnection = false; try { createdConnection = CreateConnection(ref database); DataTable deviceTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM DeviceDetail " + whereClause); if (deviceTable.Rows.Count == 0) return null; //DataRow row = deviceTable.Rows[0]; DataRow[] rowset = deviceTable.Select("NodeID = '" + CommonFunctions.CurrentNodeID() + "'"); if (rowset.Length > 0) { DataRow row = rowset[0]; Device device = new Device { NodeID = database.Guid(row, "NodeID"), ID = row.ConvertField<int>("ID"), ParentID = row.ConvertNullableField<int>("ParentID"), UniqueID = database.Guid(row, "UniqueID"), Acronym = row.Field<string>("Acronym"), Name = row.Field<string>("Name"), IsConcentrator = Convert.ToBoolean(row.Field<object>("IsConcentrator")), CompanyID = row.ConvertNullableField<int>("CompanyID"), HistorianID = row.ConvertNullableField<int>("HistorianID"), AccessID = row.ConvertField<int>("AccessID"), VendorDeviceID = row.ConvertNullableField<int>("VendorDeviceID"), ProtocolID = row.ConvertNullableField<int>("ProtocolID"), Longitude = row.ConvertNullableField<decimal>("Longitude"), Latitude = row.ConvertNullableField<decimal>("Latitude"), InterconnectionID = row.ConvertNullableField<int>("InterconnectionID"), ConnectionString = ParseConnectionString(row.Field<string>("ConnectionString").ToNonNullString()), AlternateCommandChannel = ParseAlternateCommand(row.Field<string>("ConnectionString").ToNonNullString()), TimeZone = row.Field<string>("TimeZone"), FramesPerSecond = Convert.ToInt32(row.Field<object>("FramesPerSecond") ?? 30), TimeAdjustmentTicks = Convert.ToInt64(row.Field<object>("TimeAdjustmentTicks")), DataLossInterval = row.ConvertField<double>("DataLossInterval"), ContactList = row.Field<string>("ContactList"), MeasuredLines = row.ConvertNullableField<int>("MeasuredLines"), LoadOrder = row.ConvertField<int>("LoadOrder"), Enabled = Convert.ToBoolean(row.Field<object>("Enabled")), CreatedOn = row.Field<DateTime>("CreatedOn"), AllowedParsingExceptions = Convert.ToInt32(row.Field<object>("AllowedParsingExceptions")), ParsingExceptionWindow = row.ConvertField<double>("ParsingExceptionWindow"), DelayedConnectionInterval = row.ConvertField<double>("DelayedConnectionInterval"), AllowUseOfCachedConfiguration = Convert.ToBoolean(row.Field<object>("AllowUseOfCachedConfiguration")), AutoStartDataParsingSequence = Convert.ToBoolean(row.Field<object>("AutoStartDataParsingSequence")), SkipDisableRealTimeData = Convert.ToBoolean(row.Field<object>("SkipDisableRealTimeData")), MeasurementReportingInterval = Convert.ToInt32(row.Field<object>("MeasurementReportingInterval")), ConnectOnDemand = Convert.ToBoolean(row.Field<object>("ConnectOnDemand")), m_companyName = row.Field<string>("CompanyName"), m_companyAcronym = row.Field<string>("CompanyAcronym"), m_historianAcronym = row.Field<string>("HistorianAcronym"), m_vendorDeviceName = row.Field<string>("VendorDeviceName"), m_vendorAcronym = row.Field<string>("VendorAcronym"), m_protocolName = row.Field<string>("ProtocolName"), m_protocolCategory = row.Field<string>("Category"), m_interconnectionName = row.Field<string>("InterconnectionName"), m_nodeName = row.Field<string>("NodeName"), m_parentAcronym = row.Field<string>("ParentAcronym"), m_originalSource = row.Field<string>("OriginalSource") }; return device; } return null; } finally { if (createdConnection && database != null) database.Dispose(); } }
/// <summary> /// Deletes specified <see cref="Device"/> record from database. /// </summary> /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param> /// <param name="device">Device to be deleted.</param> /// <returns>String, for display use, indicating success.</returns> public static string Delete(AdoDataConnection database, Device device) { bool createdConnection = false; try { createdConnection = CreateConnection(ref database); // Setup current user context for any delete triggers CommonFunctions.SetCurrentUserContext(database); // Does not delete the Parent Device database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("UPDATE Device SET ParentID = null WHERE ParentID = {0}", "OldParentID", "NewParentID"), DefaultTimeout, device.ID); // Deletes the Parent Device //database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM Device WHERE ParentID = {0}", "ParentID"), DefaultTimeout, device.ID); database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM Device WHERE ID = {0}", "deviceID"), DefaultTimeout, device.ID); database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM OutputStreamDevice WHERE Acronym = {0}", "deviceAcronym"), DefaultTimeout, device.Acronym); return "Device deleted successfully"; } finally { if (createdConnection && database != null) database.Dispose(); } }
/// <summary> /// Saves <see cref="Device"/> information to database along with analogs and digital measurements if requested.. /// </summary> /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param> /// <param name="device">Information about <see cref="Device"/>.</param> /// <param name="notifyService">Boolean value to notify service if needed.</param> /// <param name="digitalCount">Number of digital measurements to add.</param> /// <param name="analogCount">Number of analog measurements to add.</param> /// <param name="digitalLabels">Collection of digital labels associated with a device in configuration frame.</param> /// <param name="analogLabels">Collection of analog labels associated with a device in configuration frame.</param> /// <returns>String, for display use, indicating success.</returns> public static string SaveWithAnalogsDigitals(AdoDataConnection database, Device device, bool notifyService, int digitalCount, int analogCount, List<string> digitalLabels = null, List<string> analogLabels = null) { bool createdConnection = false; string query; try { Device oldDevice = null; createdConnection = CreateConnection(ref database); object nodeID; if (device.NodeID == Guid.Empty) nodeID = database.CurrentNodeID(); else nodeID = database.Guid(device.NodeID); if (device.ID == 0) { query = database.ParameterizedQueryString("INSERT INTO Device (NodeID, ParentID, UniqueID, Acronym, Name, IsConcentrator, CompanyID, HistorianID, AccessID, VendorDeviceID, " + "ProtocolID, Longitude, Latitude, InterconnectionID, ConnectionString, TimeZone, FramesPerSecond, TimeAdjustmentTicks, DataLossInterval, ContactList, " + "MeasuredLines, LoadOrder, Enabled, AllowedParsingExceptions, ParsingExceptionWindow, DelayedConnectionInterval, AllowUseOfCachedConfiguration, " + "AutoStartDataParsingSequence, SkipDisableRealTimeData, MeasurementReportingInterval, ConnectOndemand, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) Values " + "({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, " + "{26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34})", "nodeID", "parentID", "uniqueID", "acronym", "name", "isConcentrator", "companyID", "historianID", "accessID", "vendorDeviceID", "protocolID", "longitude", "latitude", "interconnectionID", "connectionString", "timezone", "framesPerSecond", "timeAdjustmentTicks", "dataLossInterval", "contactList", "measuredLines", "loadOrder", "enabled", "allowedParsingExceptions", "parsingExceptionWindow", "delayedConnectionInterval", "allowUseOfCachedConfiguration", "autoStartDataParsingSequence", "skipDisableRealTimeData", "measurementReportingInterval", "connectOndemand", "updatedBy", "updatedOn", "createdBy", "createdOn"); database.Connection.ExecuteNonQuery(query, DefaultTimeout, nodeID, device.ParentID.ToNotNull(), database.Guid(Guid.NewGuid()), device.Acronym.Replace(" ", "").ToUpper(), device.Name.ToNotNull(), database.Bool(device.IsConcentrator), device.CompanyID.ToNotNull(), device.HistorianID.ToNotNull(), device.AccessID, device.VendorDeviceID.ToNotNull(), device.ProtocolID.ToNotNull(), device.Longitude.ToNotNull(), device.Latitude.ToNotNull(), device.InterconnectionID.ToNotNull(), BuildConnectionString(device), device.TimeZone.ToNotNull(), device.FramesPerSecond ?? 30, device.TimeAdjustmentTicks, device.DataLossInterval, device.ContactList.ToNotNull(), device.MeasuredLines.ToNotNull(), device.LoadOrder, database.Bool(device.Enabled), device.AllowedParsingExceptions, device.ParsingExceptionWindow, device.DelayedConnectionInterval, database.Bool(device.AllowUseOfCachedConfiguration), database.Bool(device.AutoStartDataParsingSequence), database.Bool(device.SkipDisableRealTimeData), device.MeasurementReportingInterval, database.Bool(device.ConnectOnDemand), CommonFunctions.CurrentUser, database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow); } else { oldDevice = GetDevice(database, " WHERE ID = " + device.ID); query = database.ParameterizedQueryString("UPDATE Device SET NodeID = {0}, ParentID = {1}, UniqueID = {2}, Acronym = {3}, Name = {4}, " + "IsConcentrator = {5}, CompanyID = {6}, HistorianID = {7}, AccessID = {8}, VendorDeviceID = {9}, ProtocolID = {10}, Longitude = {11}, " + "Latitude = {12}, InterconnectionID = {13}, ConnectionString = {14}, TimeZone = {15}, FramesPerSecond = {16}, TimeAdjustmentTicks = {17}, " + "DataLossInterval = {18}, ContactList = {19}, MeasuredLines = {20}, LoadOrder = {21}, Enabled = {22}, AllowedParsingExceptions = {23}, " + "ParsingExceptionWindow = {24}, DelayedConnectionInterval = {25}, AllowUseOfCachedConfiguration = {26}, AutoStartDataParsingSequence = {27}, " + "SkipDisableRealTimeData = {28}, MeasurementReportingInterval = {29}, ConnectOnDemand = {30}, UpdatedBy = {31}, UpdatedOn = {32} WHERE ID = {33}", "nodeID", "parentID", "uniqueID", "acronym", "name", "isConcentrator", "companyID", "historianID", "accessID", "vendorDeviceID", "protocolID", "longitude", "latitude", "interconnectionID", "connectionString", "timezone", "framesPerSecond", "timeAdjustmentTicks", "dataLossInterval", "contactList", "measuredLines", "loadOrder", "enabled", "allowedParsingExceptions", "parsingExceptionWindow", "delayedConnectionInterval", "allowUseOfCachedConfiguration", "autoStartDataParsingSequence", "skipDisableRealTimeData", "measurementReportingInterval", "connectOnDemand", "updatedBy", "updatedOn", "id"); database.Connection.ExecuteNonQuery(query, DefaultTimeout, nodeID, device.ParentID.ToNotNull(), database.Guid(device.UniqueID), device.Acronym.Replace(" ", "").ToUpper(), device.Name.ToNotNull(), database.Bool(device.IsConcentrator), device.CompanyID.ToNotNull(), device.HistorianID.ToNotNull(), device.AccessID, device.VendorDeviceID.ToNotNull(), device.ProtocolID.ToNotNull(), device.Longitude.ToNotNull(), device.Latitude.ToNotNull(), device.InterconnectionID.ToNotNull(), BuildConnectionString(device), device.TimeZone.ToNotNull(), device.FramesPerSecond ?? 30, device.TimeAdjustmentTicks, device.DataLossInterval, device.ContactList.ToNotNull(), device.MeasuredLines.ToNotNull(), device.LoadOrder, database.Bool(device.Enabled), device.AllowedParsingExceptions, device.ParsingExceptionWindow, device.DelayedConnectionInterval, database.Bool(device.AllowUseOfCachedConfiguration), database.Bool(device.AutoStartDataParsingSequence), database.Bool(device.SkipDisableRealTimeData), device.MeasurementReportingInterval, database.Bool(device.ConnectOnDemand), CommonFunctions.CurrentUser, database.UtcNow, device.ID); } Device savedDevice = GetDevice(database, "WHERE Acronym = '" + device.Acronym.Replace(" ", "").ToUpper() + "'"); if ((object)savedDevice == null) return "Device information saved successfully but failed to create measurements"; // Determine if device is using a phasor protocol bool deviceIsUsingPhasorProtocol = (string.Compare(savedDevice.ProtocolCategory, "Phasor", StringComparison.OrdinalIgnoreCase) == 0); // Add default measurements for non-concentrator devices when device protocol category is Phasor if (!savedDevice.IsConcentrator && deviceIsUsingPhasorProtocol) { // Setup and/or validate default signals associated with non-concentrator devices (e.g., directly connected PMUs or PMUs in a concentrator) foreach (TimeSeries.UI.DataModels.SignalType signal in TimeSeries.UI.DataModels.SignalType.GetPmuSignalTypes()) { Measurement measurement; if (signal.Suffix == "AV" && analogCount > 0) { for (int i = 1; i <= analogCount; i++) { measurement = Measurement.GetMeasurement(database, "WHERE DeviceID = " + savedDevice.ID + " AND SignalReference = '" + savedDevice.Acronym + "-AV" + i + "'"); if ((object)measurement == null) { measurement = new Measurement(); measurement.DeviceID = savedDevice.ID; measurement.HistorianID = savedDevice.HistorianID; measurement.PointTag = CommonPhasorServices.CreatePointTag(savedDevice.CompanyAcronym, savedDevice.Acronym, savedDevice.VendorAcronym, "ALOG", i); measurement.SignalReference = savedDevice.Acronym + "-AV" + i; measurement.Description = savedDevice.Name + (string.IsNullOrWhiteSpace(savedDevice.VendorDeviceName) ? "" : " " + savedDevice.VendorDeviceName) + " Analog Value " + i; measurement.SignalTypeID = signal.ID; measurement.PhasorSourceIndex = (int?)null; measurement.Enabled = true; if ((object)analogLabels != null && (object)analogLabels[i - 1] != null) measurement.AlternateTag = analogLabels[i - 1]; Measurement.Save(database, measurement); } else if (measurement.SignalTypeID != signal.ID) { // Correct signal type if it has been changed measurement.SignalTypeID = signal.ID; Measurement.Save(database, measurement); } } } else if (signal.Suffix == "DV" && digitalCount > 0) { for (int i = 1; i <= digitalCount; i++) { measurement = Measurement.GetMeasurement(database, "WHERE DeviceID = " + savedDevice.ID + " AND SignalReference = '" + savedDevice.Acronym + "-DV" + i + "'"); if ((object)measurement == null) { measurement = new Measurement(); measurement.DeviceID = savedDevice.ID; measurement.HistorianID = savedDevice.HistorianID; measurement.PointTag = CommonPhasorServices.CreatePointTag(savedDevice.CompanyAcronym, savedDevice.Acronym, savedDevice.VendorAcronym, "DIGI", i); measurement.SignalReference = savedDevice.Acronym + "-DV" + i; measurement.SignalTypeID = signal.ID; measurement.Description = savedDevice.Name + (string.IsNullOrWhiteSpace(savedDevice.VendorDeviceName) ? "" : " " + savedDevice.VendorDeviceName) + " Digital Value " + i; measurement.PhasorSourceIndex = (int?)null; measurement.Enabled = true; if ((object)digitalLabels != null && (object)digitalLabels[i - 1] != null) measurement.AlternateTag = digitalLabels[i - 1]; Measurement.Save(database, measurement); } else if (measurement.SignalTypeID != signal.ID) { // Correct signal type if it has been changed measurement.SignalTypeID = signal.ID; Measurement.Save(database, measurement); } } } else if (signal.Suffix == "FQ" || signal.Suffix == "DF" || signal.Suffix == "SF") { measurement = Measurement.GetMeasurement(database, "WHERE DeviceID = " + savedDevice.ID + " AND SignalTypeSuffix = '" + signal.Suffix + "'"); if ((object)measurement == null) { measurement = new Measurement(); measurement.DeviceID = savedDevice.ID; measurement.HistorianID = savedDevice.HistorianID; measurement.PointTag = CommonPhasorServices.CreatePointTag(savedDevice.CompanyAcronym, savedDevice.Acronym, savedDevice.VendorAcronym, signal.Acronym); measurement.SignalReference = savedDevice.Acronym + "-" + signal.Suffix; measurement.SignalTypeID = signal.ID; measurement.Description = savedDevice.Name + (string.IsNullOrWhiteSpace(savedDevice.VendorDeviceName) ? "" : " " + savedDevice.VendorDeviceName) + " " + signal.Name; measurement.PhasorSourceIndex = (int?)null; measurement.Enabled = true; Measurement.Save(database, measurement); } // Based on query filter of SignalTypeSuffix, the following will never be true //else if (measurement.SignalTypeID != signal.ID) //{ // // Correct signal type if it has been changed // measurement.SignalTypeID = signal.ID; // Measurement.Save(database, measurement); //} } } } if (device.ID > 0) { if (!device.IsConcentrator) { // For existing non-concentrator devices, call Save on each phasor so that measurements related to those phasors will reflect possible device changes. IList<int> keys = Phasor.LoadKeys(database, device.ID); foreach (Phasor phasor in Phasor.Load(database, keys)) { Phasor.SaveWithoutMeasurementUpdate(database, phasor); } } // Update existing device measurements to reflect possible device changes if ((object)oldDevice != null) { bool companyUpdated = (deviceIsUsingPhasorProtocol && savedDevice.CompanyID != oldDevice.CompanyID); bool deviceRenamed = (deviceIsUsingPhasorProtocol && (string.CompareOrdinal(savedDevice.Acronym, oldDevice.Acronym) != 0 || string.CompareOrdinal(savedDevice.Name, oldDevice.Name) != 0)); bool historianUpdated = (savedDevice.HistorianID != oldDevice.HistorianID); if (companyUpdated || deviceRenamed || historianUpdated) { string companyAcronym = ""; int underScoreIndex; if (companyUpdated) { if (savedDevice.CompanyID.HasValue && !string.IsNullOrWhiteSpace(savedDevice.CompanyAcronym)) companyAcronym = savedDevice.CompanyAcronym; } foreach (Measurement measurement in Measurement.GetMeasurements(database, "WHERE DeviceID = " + oldDevice.ID)) { if (companyUpdated) { // WARNING: This assumes company name is followed by an underscore - this may not be a valid assumption for custom point tag naming conventions underScoreIndex = measurement.PointTag.ToNonNullString().IndexOf('_'); if (underScoreIndex > -1) measurement.PointTag = companyAcronym + measurement.PointTag.Substring(underScoreIndex); } if (deviceRenamed) { measurement.PointTag = measurement.PointTag.Replace(oldDevice.Acronym, savedDevice.Acronym); measurement.SignalReference = measurement.SignalReference.Replace(oldDevice.Acronym, savedDevice.Acronym); measurement.Description = Regex.Replace(measurement.Description.ToNonNullString(), oldDevice.Name, savedDevice.Name, RegexOptions.IgnoreCase); } if (historianUpdated && string.Compare(measurement.HistorianAcronym, "STAT", StringComparison.OrdinalIgnoreCase) != 0) measurement.HistorianID = savedDevice.HistorianID; Measurement.Save(database, measurement); } } // If changing the historian for a concentrator style device - must assume desire to change historian for all children devices if (historianUpdated && device.IsConcentrator) { foreach (Device childDevice in GetDevices(database, "WHERE ParentID = " + device.ID)) { // Recursively call this function for each child device with updated historian which will also fix measurement's historian childDevice.HistorianID = savedDevice.HistorianID; SaveWithAnalogsDigitals(database, childDevice, false, 0, 0); } } } } try { // Notify service about configuration changes made here. if (notifyService) NotifyService(savedDevice); } catch (Exception ex) { return "Device information saved successfully. Failed to send Initialize command to backend service." + Environment.NewLine + ex.Message; } return "Device information saved successfully"; } finally { if (createdConnection && database != null) database.Dispose(); } }
/// <summary> /// Saves <see cref="Device"/> information to database. /// </summary> /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param> /// <param name="device">Information about <see cref="Device"/>.</param> /// <returns>String, for display use, indicating success.</returns> public static string Save(AdoDataConnection database, Device device) { return SaveWithAnalogsDigitals(database, device, true, 0, 0); }
/// <summary> /// Loads <see cref="Device"/> 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 measurement to be loaded from the database</param> /// <returns>Collection of <see cref="Device"/>.</returns> public static ObservableCollection<Device> Load(AdoDataConnection database, IList<int> keys) { bool createdConnection = false; try { createdConnection = CreateConnection(ref database); string query; string commaSeparatedKeys; Device[] deviceList = null; DataTable deviceTable; int id; if ((object)keys != null && keys.Count > 0) { commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => str1 + "," + str2); query = string.Format("SELECT * FROM DeviceDetail WHERE ID IN ({0})", commaSeparatedKeys); deviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout); deviceList = new Device[deviceTable.Rows.Count]; foreach (DataRow row in deviceTable.Rows) { id = row.ConvertField<int>("ID"); deviceList[keys.IndexOf(id)] = new Device() { NodeID = database.Guid(row, "NodeID"), ID = id, ParentID = row.ConvertNullableField<int>("ParentID"), UniqueID = database.Guid(row, "UniqueID"), Acronym = row.Field<string>("Acronym"), Name = row.Field<string>("Name"), IsConcentrator = Convert.ToBoolean(row.Field<object>("IsConcentrator")), CompanyID = row.ConvertNullableField<int>("CompanyID"), HistorianID = row.ConvertNullableField<int>("HistorianID"), AccessID = row.ConvertField<int>("AccessID"), VendorDeviceID = row.ConvertNullableField<int>("VendorDeviceID"), ProtocolID = row.ConvertNullableField<int>("ProtocolID"), Longitude = row.ConvertNullableField<decimal>("Longitude"), Latitude = row.ConvertNullableField<decimal>("Latitude"), InterconnectionID = row.ConvertNullableField<int>("InterconnectionID"), ConnectionString = ParseConnectionString(row.Field<string>("ConnectionString").ToNonNullString()), AlternateCommandChannel = ParseAlternateCommand(row.Field<string>("ConnectionString").ToNonNullString()), TimeZone = row.Field<string>("TimeZone"), FramesPerSecond = Convert.ToInt32(row.Field<object>("FramesPerSecond") ?? 30), TimeAdjustmentTicks = Convert.ToInt64(row.Field<object>("TimeAdjustmentTicks")), DataLossInterval = row.ConvertField<double>("DataLossInterval"), ContactList = row.Field<string>("ContactList"), MeasuredLines = row.ConvertNullableField<int>("MeasuredLines"), LoadOrder = row.ConvertField<int>("LoadOrder"), Enabled = Convert.ToBoolean(row.Field<object>("Enabled")), CreatedOn = row.Field<DateTime>("CreatedOn"), AllowedParsingExceptions = Convert.ToInt32(row.Field<object>("AllowedParsingExceptions")), ParsingExceptionWindow = row.ConvertField<double>("ParsingExceptionWindow"), DelayedConnectionInterval = row.ConvertField<double>("DelayedConnectionInterval"), AllowUseOfCachedConfiguration = Convert.ToBoolean(row.Field<object>("AllowUseOfCachedConfiguration")), AutoStartDataParsingSequence = Convert.ToBoolean(row.Field<object>("AutoStartDataParsingSequence")), SkipDisableRealTimeData = Convert.ToBoolean(row.Field<object>("SkipDisableRealTimeData")), MeasurementReportingInterval = Convert.ToInt32(row.Field<object>("MeasurementReportingInterval")), ConnectOnDemand = Convert.ToBoolean(row.Field<object>("ConnectOnDemand")), m_companyName = row.Field<string>("CompanyName"), m_companyAcronym = row.Field<string>("CompanyAcronym"), m_historianAcronym = row.Field<string>("HistorianAcronym"), m_vendorDeviceName = row.Field<string>("VendorDeviceName"), m_vendorAcronym = row.Field<string>("VendorAcronym"), m_protocolName = row.Field<string>("ProtocolName"), m_protocolCategory = row.Field<string>("Category"), m_interconnectionName = row.Field<string>("InterconnectionName"), m_nodeName = row.Field<string>("NodeName"), m_parentAcronym = row.Field<string>("ParentAcronym"), m_originalSource = row.Field<string>("OriginalSource") }; } } return new ObservableCollection<Device>(deviceList ?? new Device[0]); } finally { if (createdConnection && database != null) database.Dispose(); } }
// Associate the given device with the // authorization request and save it. private void SaveDevice() { const string TcpConnectionStringFormat = "interface=0.0.0.0; compression=true; autoConnect=true; securityMode={0}; " + "server={1}:{2}; {3}{4}"; const string UdpConnectionStringFormat = "interface=0.0.0.0; compression=true; autoConnect=true; securityMode={0}; " + "localport={1}; transportprotocol=udp; commandChannel={{server={2}:{3}; interface=0.0.0.0}}; {4}{5}"; Device device; SslPolicyErrors validPolicyErrors; X509ChainStatusFlags validChainFlags; string securitySpecificSettings = string.Empty; string dataGapRecoverySettings = string.Empty; if (SecurityMode == SecurityMode.None) { securitySpecificSettings = string.Format("internal={0}; receiveInternalMetadata={1}; receiveExternalMetadata={2}; outputMeasurements={{FILTER ActiveMeasurements WHERE Protocol = 'GatewayTransport'}}", !(m_receiveExternalMetadata && !m_receiveInternalMetadata), m_receiveInternalMetadata, m_receiveExternalMetadata); } else if (SecurityMode == SecurityMode.Gateway) { securitySpecificSettings = string.Format("sharedSecret={0}; authenticationID={{{1}}}", SharedKey, IdentityCertificate); } else if (SecurityMode == SecurityMode.TLS) { if (!Enum.TryParse(ValidPolicyErrors, out validPolicyErrors)) validPolicyErrors = SslPolicyErrors.None; if (!Enum.TryParse(ValidChainFlags, out validChainFlags)) validChainFlags = X509ChainStatusFlags.NoError; if (RemoteCertificateIsSelfSigned) { validPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors; validChainFlags |= X509ChainStatusFlags.UntrustedRoot; } securitySpecificSettings = string.Format("{0}remoteCertificate={1}; validPolicyErrors={2}; validChainFlags={3}; checkCertificateRevocation={4}", GetLocalCertificateSetting(), RemoteCertificateFile, validPolicyErrors, validChainFlags, !m_isRemoteCertificateSelfSigned); } if (m_enableDataGapRecovery) dataGapRecoverySettings = string.Format("; dataGapRecovery={{enabled=true; recoveryStartDelay={0}; dataMonitoringInterval={1}; minimumRecoverySpan={2}; maximumRecoverySpan={3}; recoveryProcessingInterval={4}}}{5}", m_recoveryStartDelay, m_dataMonitoringInterval, m_minimumRecoverySpan, m_maximumRecoverySpan * Time.SecondsPerDay, m_recoveryProcessingInterval, string.IsNullOrWhiteSpace(m_loggingPath) ? "" : "; loggingPath=" + m_loggingPath); device = new Device(); device.Acronym = PublisherAcronym.Replace(" ", ""); device.Name = PublisherName; device.Enabled = m_securityMode == SecurityMode.None; // TODO: Is this good logic? What if I want to tweak my subscribed measurement filter before I synchronize metadata? device.IsConcentrator = true; device.ProtocolID = GetGatewayProtocolID(); if (UseUdpDataChannel) device.ConnectionString = string.Format(UdpConnectionStringFormat, SecurityMode, UdpDataChannelPort, Hostname, PublisherPort, securitySpecificSettings, dataGapRecoverySettings); else device.ConnectionString = string.Format(TcpConnectionStringFormat, SecurityMode, Hostname, PublisherPort, securitySpecificSettings, dataGapRecoverySettings); try { Device.Save(null, device); } catch (ApplicationException ex) { CommonFunctions.LogException(null, "Save Subscriber Device", ex); } device = Device.GetDevice(null, "WHERE Acronym = '" + device.Acronym + "'"); CommonFunctions.LoadUserControl("Manage Device Configuration", typeof(DeviceUserControl), device); }