Ejemplo n.º 1
0
        private static CustomActionAdapter GetOrAddActionAdapter(TableOperations <CustomActionAdapter> actionAdapterTable, string tielineID, out bool newAdd)
        {
            string adapterName = $"IMPEDANCE_{tielineID}_CALC";
            CustomActionAdapter actionAdapter = actionAdapterTable.QueryRecordWhere("NodeID = {0} AND AdapterName = {1}", nodeID, adapterName);

            if ((object)actionAdapter == null)
            {
                actionAdapter = actionAdapterTable.NewRecord();

                actionAdapter.NodeID       = nodeID;
                actionAdapter.AdapterName  = adapterName;
                actionAdapter.AssemblyName = AssemblyName;
                actionAdapter.TypeName     = TypeName;

                actionAdapterTable.AddNewRecord(actionAdapter);

                // Re-query newly added record to get auto-increment ID
                actionAdapter = actionAdapterTable.QueryRecordWhere("NodeID = {0} AND AdapterName = {1}", nodeID, adapterName);
                newAdd        = true;

                if ((object)actionAdapter == null)
                {
                    throw new InvalidOperationException($"Failed to lookup CustomActionAdapter record with AdapterName of \"{adapterName}\".");
                }
            }
            else
            {
                newAdd = false;
            }

            return(actionAdapter);
        }
Ejemplo n.º 2
0
        public int GetDefaultIGridConnectionProfileID()
        {
            TableOperations <ConnectionProfileTaskQueue> profileTaskQueueTable = DataContext.Table <ConnectionProfileTaskQueue>();
            TableOperations <ConnectionProfile>          profileTable          = DataContext.Table <ConnectionProfile>();
            ConnectionProfile profile = profileTable.QueryRecordWhere("Name = {0}", DefaultIGridConnectionProfileName);

            if ((object)profile == null)
            {
                ConnectionProfileTaskQueue profileTaskQueue = profileTaskQueueTable.NewRecord();
                profileTaskQueue.Name                 = DefaultIGridConnectionProfileTaskQueueName;
                profileTaskQueue.MaxThreadCount       = 4;
                profileTaskQueue.UseBackgroundThreads = false;
                profileTaskQueue.Description          = "Connection Profile Task for I-Grid Devices";
                profileTaskQueueTable.AddNewRecord(profileTaskQueue);
                profileTaskQueue = profileTaskQueueTable.QueryRecordWhere("Name = {0}", DefaultIGridConnectionProfileTaskQueueName);

                profile                    = profileTable.NewRecord();
                profile.Name               = DefaultIGridConnectionProfileName;
                profile.Description        = "Connection Profile for I-Grid Devices";
                profile.DefaultTaskQueueID = profileTaskQueue.ID;
                profileTable.AddNewRecord(profile);
                profile.ID = GetDefaultIGridConnectionProfileID();

                TableOperations <ConnectionProfileTask> profileTaskTable = DataContext.Table <ConnectionProfileTask>();
                profileTaskTable.RootQueryRestriction[0] = profile.ID;
                int taskCount = profileTaskTable.QueryRecordCount();

                if (taskCount == 0)
                {
                    ConnectionProfileTask         profileTask         = profileTaskTable.NewRecord();
                    ConnectionProfileTaskSettings profileTaskSettings = profileTask.Settings;

                    profileTask.ConnectionProfileID = profile.ID;
                    profileTask.Name = "I-Grid Default Downloader Task";

                    profileTaskSettings.FileExtensions            = "*.*";
                    profileTaskSettings.RemotePath                = "/";
                    profileTaskSettings.LocalPath                 = Program.Host.Model.Global.DefaultLocalPath;
                    profileTaskSettings.ExternalOperation         = "IGridDownloader.exe <DeviceID> <TaskID>";
                    profileTaskSettings.DirectoryNamingExpression = @"<YYYY><MM>\<DeviceFolderName>";

                    profileTaskTable.AddNewRecord(profileTask);
                }
            }

            return(profile.ID);
        }
Ejemplo n.º 3
0
        private static string[] GetOutputMeasurements(TableOperations <Measurement> measurementTable, int deviceID, string tieLineID, string sender, string receiver, OrderedDictionary outputTypes)
        {
            List <Measurement> measurements = new List <Measurement>();

            foreach (string outputType in outputTypes.Keys)
            {
                string pointTag    = $"IMPEDANCE_{tieLineID}-{outputType}:CV";
                string description = $"{tieLineID} [{sender} => {receiver}] Calculated {outputTypes[outputType]} Value";

                Measurement measurement = measurementTable.QueryRecordWhere("PointTag = {0}", pointTag);

                if ((object)measurement == null)
                {
                    measurement = measurementTable.NewRecord();

                    measurement.DeviceID        = deviceID;
                    measurement.PointTag        = pointTag;
                    measurement.SignalReference = pointTag;
                    measurement.Description     = description;
                    measurement.Enabled         = true;

                    measurementTable.AddNewRecord(measurement);
                    measurement = measurementTable.QueryRecordWhere("PointTag = {0}", pointTag);

                    if ((object)measurement == null)
                    {
                        throw new InvalidOperationException($"Failed to lookup Measurement record with PointTag of \"{pointTag}\".");
                    }
                }
                else
                {
                    measurement.Description = description;
                    measurementTable.UpdateRecord(measurement);
                }

                measurements.Add(measurement);
            }

            return(measurements.Select(m => m.SignalID.ToString()).ToArray());
        }
Ejemplo n.º 4
0
        private static Device GetOrAddDevice(TableOperations <Device> deviceTable, string acronym)
        {
            Device device = deviceTable.QueryRecordWhere("NodeID = {0} AND Acronym = {1}", nodeID, acronym);

            if ((object)device == null)
            {
                device = deviceTable.NewRecord();

                device.NodeID  = nodeID;
                device.Acronym = acronym;
                device.Name    = acronym;

                deviceTable.AddNewRecord(device);
                device = deviceTable.QueryRecordWhere("NodeID = {0} AND Acronym = {1}", nodeID, acronym);

                if ((object)device == null)
                {
                    throw new InvalidOperationException($"Failed to lookup Device record with Acronym of \"{acronym}\".");
                }
            }

            return(device);
        }
Ejemplo n.º 5
0
        public IEnumerable <IGridDevice> QueryIGridDevices(string baseURL)
        {
            TableOperations <Device> deviceTable = DataContext.Table <Device>();
            XDocument document = XDocument.Load($"{baseURL}&action=getMonitorList");

            foreach (XElement monitor in document.Descendants("monitor"))
            {
                decimal  longitude, latitude;
                XElement location       = monitor.Element("location");
                XElement identification = monitor.Element("identification");
                XElement model          = monitor.Element("model");

                string serialNumber = identification?.Element("serialNumber")?.Value;
                string modelNumber  = model?.Element("number")?.Value;
                string monitorName  = identification?.Element("monitorName")?.Value;

                if (string.IsNullOrWhiteSpace(serialNumber) || string.IsNullOrWhiteSpace(modelNumber))
                {
                    continue;
                }

                Device deviceRecord = deviceTable.QueryRecordWhere("OriginalSource = {0}", serialNumber);

                if ((object)deviceRecord == null)
                {
                    deviceRecord = deviceTable.NewRecord();

                    string acronym = monitorName ?? modelNumber;

                    // Get a clean acronym
                    acronym = acronym
                              .ToUpperInvariant()
                              .ReplaceCharacters(' ', s_isInvalidAcronymChar)
                              .RemoveDuplicateWhiteSpace();

                    // Truncate at any numbers in the acronym, note this is based on sample data naming convention
                    int index = acronym.IndexOfAny(s_digits);

                    if (index > 0)
                    {
                        acronym = acronym.Substring(0, index);
                    }

                    acronym = acronym.Trim().ReplaceWhiteSpace('-');

                    deviceRecord.Acronym = $"{acronym}${serialNumber}";
                }

                decimal.TryParse(location?.Element("longitude")?.Value, out longitude);
                decimal.TryParse(location?.Element("latitude")?.Value, out latitude);

                yield return(new IGridDevice
                {
                    DeviceID = deviceRecord.ID,
                    Acronym = deviceRecord.Acronym,
                    SerialNumber = serialNumber,
                    Name = monitorName,
                    Description = model.Element("description")?.Value,
                    ModelNumber = modelNumber,
                    Longitude = longitude,
                    Latitude = latitude,
                    Selected = deviceRecord.ID == 0
                });
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Gets measurement record, creating it if needed.
        /// </summary>
        /// <param name="instance">Target <see cref="IIndependentAdapterManager"/> instance.</param>
        /// <param name="currentDeviceID">Device ID associated with current adapter, or zero if none.</param>
        /// <param name="pointTag">Point tag of measurement.</param>
        /// <param name="signalReference">Signal reference of measurement.</param>
        /// <param name="description">Description of measurement.</param>
        /// <param name="signalType">Signal type of measurement.</param>
        /// <param name="targetHistorianAcronym">Acronym of target historian for measurement.</param>
        /// <returns>Measurement record.</returns>
        public static MeasurementRecord GetMeasurementRecord(this IIndependentAdapterManager instance, int currentDeviceID, string pointTag, string signalReference, string description, SignalType signalType = SignalType.CALC, string targetHistorianAcronym = "PPA")
        {
            // Open database connection as defined in configuration file "systemSettings" category
            using (AdoDataConnection connection = instance.GetConfiguredConnection())
            {
                TableOperations <DeviceRecord>      deviceTable      = new TableOperations <DeviceRecord>(connection);
                TableOperations <MeasurementRecord> measurementTable = new TableOperations <MeasurementRecord>(connection);
                TableOperations <HistorianRecord>   historianTable   = new TableOperations <HistorianRecord>(connection);
                TableOperations <SignalTypeRecord>  signalTypeTable  = new TableOperations <SignalTypeRecord>(connection);

                // Lookup target device ID
                int?deviceID = currentDeviceID > 0 ? currentDeviceID : deviceTable.QueryRecordWhere("Acronym = {0}", instance.Name)?.ID;

                // Lookup target historian ID
                int?historianID = historianTable.QueryRecordWhere("Acronym = {0}", targetHistorianAcronym)?.ID;

                // Lookup signal type ID
                int signalTypeID = signalTypeTable.QueryRecordWhere("Acronym = {0}", signalType.ToString())?.ID ?? 1;

                // Lookup measurement record by point tag, creating a new record if one does not exist
                MeasurementRecord measurement = measurementTable.QueryRecordWhere("PointTag = {0}", pointTag) ?? measurementTable.NewRecord();

                // Update record fields
                measurement.DeviceID        = deviceID;
                measurement.HistorianID     = historianID;
                measurement.PointTag        = pointTag;
                measurement.SignalReference = signalReference;
                measurement.SignalTypeID    = signalTypeID;
                measurement.Description     = description;

                // Save record updates
                measurementTable.AddNewOrUpdateRecord(measurement);

                // Re-query new records to get any database assigned information, e.g., unique Guid-based signal ID
                if (measurement.PointID == 0)
                {
                    measurement = measurementTable.QueryRecordWhere("PointTag = {0}", pointTag);
                }

                // Notify host system of configuration changes
                instance.OnConfigurationChanged();

                return(measurement);
            }
        }
Ejemplo n.º 7
0
        private void SetupGrafanaHostingAdapter()
        {
            try
            {
                const string GrafanaProcessAdapterName = "GRAFANA!PROCESS";
                const string DefaultGrafanaServerPath  = GrafanaAuthProxyController.DefaultServerPath;

                const string GrafanaAdminRoleName        = GrafanaAuthProxyController.GrafanaAdminRoleName;
                const string GrafanaAdminRoleDescription = "Grafana Administrator Role";

                // Access needed settings from specified categories in configuration file
                CategorizedSettingsElementCollection systemSettings = ConfigurationFile.Current.Settings["systemSettings"];
                CategorizedSettingsElementCollection grafanaHosting = ConfigurationFile.Current.Settings["grafanaHosting"];
                string newNodeID = Guid.NewGuid().ToString();

                // Make sure needed settings exist
                systemSettings.Add("NodeID", newNodeID, "Unique Node ID");
                grafanaHosting.Add("ServerPath", DefaultGrafanaServerPath, "Defines the path to the Grafana server to host - set to empty string to disable hosting.");

                // Get settings as currently defined in configuration file
                Guid   nodeID            = Guid.Parse(systemSettings["NodeID"].ValueAs(newNodeID));
                string grafanaServerPath = grafanaHosting["ServerPath"].ValueAs(DefaultGrafanaServerPath);

                // Only enable adapter if file path to configured Grafana server executable is accessible
                bool enabled = File.Exists(FilePath.GetAbsolutePath(grafanaServerPath));

                // Open database connection as defined in configuration file "systemSettings" category
                using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
                {
                    // Make sure Grafana process adapter exists
                    TableOperations <CustomActionAdapter> actionAdapterTable = new TableOperations <CustomActionAdapter>(connection);
                    CustomActionAdapter actionAdapter = actionAdapterTable.QueryRecordWhere("AdapterName = {0}", GrafanaProcessAdapterName) ?? actionAdapterTable.NewRecord();

                    // Update record fields
                    actionAdapter.NodeID       = nodeID;
                    actionAdapter.AdapterName  = GrafanaProcessAdapterName;
                    actionAdapter.AssemblyName = "FileAdapters.dll";
                    actionAdapter.TypeName     = "FileAdapters.ProcessLauncher";
                    actionAdapter.Enabled      = enabled;

                    // Define default adapter connection string if none is defined
                    if (string.IsNullOrWhiteSpace(actionAdapter.ConnectionString))
                    {
                        actionAdapter.ConnectionString =
                            $"FileName={DefaultGrafanaServerPath}; " +
                            $"WorkingDirectory={FilePath.GetAbsolutePath("Grafana")}; " +
                            "ForceKillOnDispose=True; " +
                            "ProcessOutputAsLogMessages=True; " +
                            "LogMessageTextExpression={(?<=.*msg\\s*\\=\\s*\\\")[^\\\"]*(?=\\\")|(?<=.*file\\s*\\=\\s*\\\")[^\\\"]*(?=\\\")|(?<=.*file\\s*\\=\\s*)[^\\s]*(?=s|$)|(?<=.*path\\s*\\=\\s*\\\")[^\\\"]*(?=\\\")|(?<=.*path\\s*\\=\\s*)[^\\s]*(?=s|$)|(?<=.*error\\s*\\=\\s*\\\")[^\\\"]*(?=\\\")|(?<=.*reason\\s*\\=\\s*\\\")[^\\\"]*(?=\\\")|(?<=.*id\\s*\\=\\s*\\\")[^\\\"]*(?=\\\")|(?<=.*version\\s*\\=\\s*)[^\\s]*(?=\\s|$)|(?<=.*dbtype\\s*\\=\\s*)[^\\s]*(?=\\s|$)|(?<=.*)commit\\s*\\=\\s*[^\\s]*(?=\\s|$)|(?<=.*)compiled\\s*\\=\\s*[^\\s]*(?=\\s|$)|(?<=.*)address\\s*\\=\\s*[^\\s]*(?=\\s|$)|(?<=.*)protocol\\s*\\=\\s*[^\\s]*(?=\\s|$)|(?<=.*)subUrl\\s*\\=\\s*[^\\s]*(?=\\s|$)|(?<=.*)code\\s*\\=\\s*[^\\s]*(?=\\s|$)|(?<=.*name\\s*\\=\\s*)[^\\s]*(?=\\s|$)}; " +
                            "LogMessageLevelExpression={(?<=.*lvl\\s*\\=\\s*)[^\\s]*(?=\\s|$)}; " +
                            "LogMessageLevelMappings={info=Info; warn=Waning; error=Error; critical=Critical; debug=Debug}";
                    }

                    // Preserve connection string on existing records except for Grafana server executable path that comes from configuration file
                    Dictionary <string, string> settings = actionAdapter.ConnectionString.ParseKeyValuePairs();
                    settings["FileName"]           = grafanaServerPath;
                    actionAdapter.ConnectionString = settings.JoinKeyValuePairs();

                    // Save record updates
                    actionAdapterTable.AddNewOrUpdateRecord(actionAdapter);

                    // Make sure Grafana admin role exists
                    TableOperations <ApplicationRole> applicationRoleTable = new TableOperations <ApplicationRole>(connection);
                    ApplicationRole applicationRole = applicationRoleTable.QueryRecordWhere("Name = {0} AND NodeID = {1}", GrafanaAdminRoleName, nodeID);

                    if ((object)applicationRole == null)
                    {
                        applicationRole             = applicationRoleTable.NewRecord();
                        applicationRole.NodeID      = nodeID;
                        applicationRole.Name        = GrafanaAdminRoleName;
                        applicationRole.Description = GrafanaAdminRoleDescription;
                        applicationRoleTable.AddNewRecord(applicationRole);
                    }
                }
            }
            catch (Exception ex)
            {
                LogPublisher log = Logger.CreatePublisher(typeof(ServiceHost), MessageClass.Application);
                log.Publish(MessageLevel.Error, "Error Message", "Failed to setup Grafana hosting adapter", null, ex);
            }
        }
Ejemplo n.º 8
0
 public static Measurement NewMeasurement(this TableOperations <Measurement> measurementTable) =>
 measurementTable.NewRecord();
Ejemplo n.º 9
0
 public static Device NewDevice(this TableOperations <Device> deviceTable) =>
 deviceTable.NewRecord();
Ejemplo n.º 10
0
 public static Phasor NewPhasor(this TableOperations <Phasor> phasorTable) =>
 phasorTable.NewRecord();
Ejemplo n.º 11
0
        private void SetupRequiredAdapters()
        {
            try
            {
                const string PTPdProcessName       = "PTPD!PROCESS";
                const string StatisticServicesName = "STATISTIC!SERVICES";
                const string DataPublisherName     = "INTERNAL!DATAPUBLISHER";

                // Access needed settings from specified categories in configuration file
                CategorizedSettingsElementCollection systemSettings = ConfigurationFile.Current.Settings["systemSettings"];
                string newNodeID = Guid.NewGuid().ToString();

                // Make sure needed settings exist
                systemSettings.Add("NodeID", newNodeID, "Unique Node ID");

                // Get settings as currently defined in configuration file
                Guid nodeID = Guid.Parse(systemSettings["NodeID"].ValueAs(newNodeID));

                // Open database connection as defined in configuration file "systemSettings" category
                using (AdoDataConnection connection = new AdoDataConnection("systemSettings"))
                {
                    // Make sure Grafana process adapter exists
                    TableOperations <CustomActionAdapter> actionAdapterTable = new TableOperations <CustomActionAdapter>(connection);

                    // Make sure Grafana process adapter exists
                    CustomActionAdapter actionAdapter = actionAdapterTable.QueryRecordWhere("AdapterName = {0}", PTPdProcessName) ?? actionAdapterTable.NewRecord();

                    // Update record fields
                    actionAdapter.NodeID       = nodeID;
                    actionAdapter.AdapterName  = PTPdProcessName;
                    actionAdapter.AssemblyName = "FileAdapters.dll";
                    actionAdapter.TypeName     = "FileAdapters.ProcessLauncher";
                    actionAdapter.Enabled      = true;

                    string interfaceGuid = null;

                    // Scan network interfaces
                    try
                    {
                        NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().Where(ni =>
                                                                                                                ni.OperationalStatus == OperationalStatus.Up &&
                                                                                                                ni.NetworkInterfaceType != NetworkInterfaceType.Loopback &&
                                                                                                                ni.NetworkInterfaceType != NetworkInterfaceType.Tunnel).ToArray();

                        if (networkInterfaces.Length > 0)
                        {
                            interfaceGuid = networkInterfaces[0].Id;
                            File.WriteAllText(FilePath.GetAbsolutePath("NetworkInterfaces.txt"), $"Local Network Interfaces:\r\n\r\n{string.Join("\r\n", networkInterfaces.Select(ni => $"{ni.Name} - {ni.Description}: {ni.Id}"))}");
                        }
                    }
                    catch
                    {
                    }

                    // Define default adapter connection string if none is defined
                    if (string.IsNullOrWhiteSpace(actionAdapter.ConnectionString))
                    {
                        actionAdapter.ConnectionString = $"FileName=ptpd.exe; Arguments={{-b {interfaceGuid ?? "{InterfaceGuidHere}"} -V -g}}; ForceKillOnDispose=True";
                    }

                    // Save record updates
                    actionAdapterTable.AddNewOrUpdateRecord(actionAdapter);

                    // Make sure statistic services adapter exists
                    actionAdapter = actionAdapterTable.QueryRecordWhere("AdapterName = {0}", StatisticServicesName) ?? actionAdapterTable.NewRecord();

                    // Update record fields
                    actionAdapter.NodeID       = nodeID;
                    actionAdapter.AdapterName  = StatisticServicesName;
                    actionAdapter.AssemblyName = "GSF.TimeSeries.dll";
                    actionAdapter.TypeName     = "GSF.TimeSeries.Statistics.StatisticsEngine";
                    actionAdapter.Enabled      = true;

                    // Save record updates
                    actionAdapterTable.AddNewOrUpdateRecord(actionAdapter);

                    // Make sure internal data publisher adapter exists
                    actionAdapter = actionAdapterTable.QueryRecordWhere("AdapterName = {0}", DataPublisherName) ?? actionAdapterTable.NewRecord();

                    // Update record fields
                    actionAdapter.NodeID           = nodeID;
                    actionAdapter.AdapterName      = DataPublisherName;
                    actionAdapter.AssemblyName     = "GSF.TimeSeries.dll";
                    actionAdapter.TypeName         = "GSF.TimeSeries.Transport.DataPublisher";
                    actionAdapter.ConnectionString = "securityMode=None; allowSynchronizedSubscription=false; useBaseTimeOffsets=true; cacheMeasurementKeys={FILTER ActiveMeasurements WHERE SignalType = 'STAT'}";
                    actionAdapter.Enabled          = true;

                    // Save record updates
                    actionAdapterTable.AddNewOrUpdateRecord(actionAdapter);
                }
            }
            catch (Exception ex)
            {
                LogPublisher log = Logger.CreatePublisher(typeof(ServiceHost), MessageClass.Application);
                log.Publish(MessageLevel.Error, "Error Message", "Failed to setup PTPd hosting adapter", null, ex);
            }
        }