/// <summary>
        /// Loads configuration from the database and configures adapter to run with that configuration
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            HashSet <IMeasurement> outputMeasurements = new HashSet <IMeasurement>();

            m_configuredCalculations        = new List <PowerCalculation>();
            m_averageCalculationsPerFrame   = new RunningAverage();
            m_averageCalculationTime        = new RunningAverage();
            m_averageTotalCalculationTime   = new RunningAverage();
            m_lastActivePowerCalculations   = new ConcurrentQueue <IMeasurement>();
            m_lastReactivePowerCalculations = new ConcurrentQueue <IMeasurement>();
            m_lastApparentPowerCalculations = new ConcurrentQueue <IMeasurement>();

            string query = "SELECT " +
                           //            1                   2                     3                   4                     5
                           "ID, CircuitDescription, VoltageAngleSignalID, VoltageMagSignalID, CurrentAngleSignalID, CurrentMagSignalID, " +
                           //         6                        7                            8
                           "ActivePowerOutputSignalID, ReactivePowerOutputSignalID, ApparentPowerOutputSignalID FROM PowerCalculation " +
                           "WHERE NodeId = {0} AND Enabled <> 0 ";

            using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
                using (IDataReader rdr = database.ExecuteReader(query, ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs <Guid>()))
                {
                    while (rdr.Read())
                    {
                        m_configuredCalculations.Add(new PowerCalculation
                        {
                            PowerCalculationID             = rdr.GetInt32(0),
                            CircuitDescription             = rdr.GetString(1),
                            VoltageAngleSignalID           = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[2].ToString())),
                            VoltageMagnitudeSignalID       = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[3].ToString())),
                            CurrentAngleSignalID           = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[4].ToString())),
                            CurrentMagnitudeSignalID       = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[5].ToString())),
                            ActivePowerOutputMeasurement   = AddOutputMeasurement(Guid.Parse(rdr[6].ToString()), outputMeasurements),
                            ReactivePowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[7].ToString()), outputMeasurements),
                            ApparentPowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[8].ToString()), outputMeasurements)
                        });
                    }
                }

            if (m_configuredCalculations.Any())
            {
                InputMeasurementKeys = m_configuredCalculations.SelectMany(pc => new[] { pc.CurrentAngleSignalID, pc.CurrentMagnitudeSignalID, pc.VoltageAngleSignalID, pc.VoltageMagnitudeSignalID }).ToArray();
            }
            else
            {
                throw new InvalidOperationException("Skipped initialization of power calculator: no defined power calculations...");
            }

            if (outputMeasurements.Any())
            {
                OutputMeasurements = outputMeasurements.ToArray();
            }

            Dictionary <string, string> settings = Settings;
            string setting;

            if (settings.TryGetValue("AlwaysProduceResult", out setting))
            {
                AlwaysProduceResult = setting.ParseBoolean();
            }

            if (settings.TryGetValue("ApplySqrt3Adjustment", out setting))
            {
                ApplySqrt3Adjustment = setting.ParseBoolean();
            }

            if (settings.TryGetValue("RemoveSqrt3Adjustment", out setting))
            {
                RemoveSqrt3Adjustment = setting.ParseBoolean();
            }

            if (settings.TryGetValue("EnableTemporalProcessing", out setting))
            {
                EnableTemporalProcessing = setting.ParseBoolean();
            }
        }
        /// <summary>
        /// Loads configuration from the database and configures adapter to run with that configuration
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            HashSet <IMeasurement> outputMeasurements = new HashSet <IMeasurement>();

            m_configuredCalculations        = new List <PowerCalculation>();
            m_adjustmentStrategies          = new Dictionary <MeasurementKey, VoltageAdjustmentStrategy>();
            m_averageCalculationsPerFrame   = new RunningAverage();
            m_averageCalculationTime        = new RunningAverage();
            m_averageTotalCalculationTime   = new RunningAverage();
            m_lastActivePowerCalculations   = new ConcurrentQueue <IMeasurement>();
            m_lastReactivePowerCalculations = new ConcurrentQueue <IMeasurement>();
            m_lastApparentPowerCalculations = new ConcurrentQueue <IMeasurement>();

            if (!Settings.TryGetValue(nameof(TableName), out string tableName))
            {
                tableName = DefaultTableName;
            }

            string query = "SELECT " +
                           // 0          1                    2                     3                   4                     5
                           "ID, CircuitDescription, VoltageAngleSignalID, VoltageMagSignalID, CurrentAngleSignalID, CurrentMagSignalID, " +
                           //            6                          7                            8
                           "ActivePowerOutputSignalID, ReactivePowerOutputSignalID, ApparentPowerOutputSignalID FROM " + tableName + " " +
                           "WHERE NodeId = {0} AND Enabled <> 0 ";

            using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
                using (IDataReader rdr = database.ExecuteReader(query, ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs <Guid>()))
                {
                    while (rdr.Read())
                    {
                        m_configuredCalculations.Add(new PowerCalculation
                        {
                            PowerCalculationID             = rdr.GetInt32(0),
                            CircuitDescription             = rdr.GetString(1),
                            VoltageAngleMeasurementKey     = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[2].ToString())),
                            VoltageMagnitudeMeasurementKey = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[3].ToString())),
                            CurrentAngleMeasurementKey     = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[4].ToString())),
                            CurrentMagnitudeMeasurementKey = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[5].ToString())),
                            ActivePowerOutputMeasurement   = AddOutputMeasurement(Guid.Parse(rdr[6].ToString()), outputMeasurements),
                            ReactivePowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[7].ToString()), outputMeasurements),
                            ApparentPowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[8].ToString()), outputMeasurements)
                        });
                    }
                }

            if (m_configuredCalculations.Any())
            {
                InputMeasurementKeys = m_configuredCalculations.SelectMany(pc => new[] { pc.CurrentAngleMeasurementKey, pc.CurrentMagnitudeMeasurementKey, pc.VoltageAngleMeasurementKey, pc.VoltageMagnitudeMeasurementKey }).ToArray();
            }
            else
            {
                throw new InvalidOperationException("Skipped initialization of power calculator: no defined power calculations...");
            }

            if (outputMeasurements.Any())
            {
                OutputMeasurements = outputMeasurements.ToArray();
            }

            Dictionary <string, string> settings = Settings;

            if (settings.TryGetValue(nameof(AlwaysProduceResult), out string setting))
            {
                AlwaysProduceResult = setting.ParseBoolean();
            }

            if (settings.TryGetValue(nameof(AdjustmentStrategy), out setting) && Enum.TryParse(setting, out VoltageAdjustmentStrategy adjustmentStrategy))
            {
                AdjustmentStrategy = adjustmentStrategy;
            }

            if (settings.TryGetValue(nameof(EnableTemporalProcessing), out setting))
            {
                EnableTemporalProcessing = setting.ParseBoolean();
            }

            // Define per power calculation line adjustment strategies
            foreach (PowerCalculation powerCalculation in m_configuredCalculations)
            {
                if (powerCalculation.VoltageMagnitudeMeasurementKey is null || string.IsNullOrWhiteSpace(powerCalculation.CircuitDescription))
                {
                    continue;
                }

                try
                {
                    Dictionary <string, string> circuitSettings = powerCalculation.CircuitDescription.ParseKeyValuePairs();

                    if (circuitSettings.TryGetValue(nameof(AdjustmentStrategy), out setting) && Enum.TryParse(setting, out adjustmentStrategy))
                    {
                        m_adjustmentStrategies[powerCalculation.VoltageMagnitudeMeasurementKey] = adjustmentStrategy;
                    }
                }
                catch (Exception ex)
                {
                    OnStatusMessage(MessageLevel.Warning, $"Failed to parse settings from circuit description \"{powerCalculation.CircuitDescription}\": {ex.Message}");
                }
            }
        }
        /// <summary>
        /// Loads configuration from the database and configures adapter to run with that configuration
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            HashSet<IMeasurement> outputMeasurements = new HashSet<IMeasurement>();

            m_configuredCalculations = new List<PowerCalculation>();
            m_averageCalculationsPerFrame = new RunningAverage();
            m_averageCalculationTime = new RunningAverage();
            m_averageTotalCalculationTime = new RunningAverage();
            m_lastActivePowerCalculations = new ConcurrentQueue<IMeasurement>();
            m_lastReactivePowerCalculations = new ConcurrentQueue<IMeasurement>();
            m_lastApparentPowerCalculations = new ConcurrentQueue<IMeasurement>();

            string query = "SELECT " +
                           //            1                   2                     3                   4                     5
                           "ID, CircuitDescription, VoltageAngleSignalID, VoltageMagSignalID, CurrentAngleSignalID, CurrentMagSignalID, " +
                           //         6                        7                            8
                           "ActivePowerOutputSignalID, ReactivePowerOutputSignalID, ApparentPowerOutputSignalID FROM PowerCalculation " +
                           "WHERE NodeId = {0} AND Enabled <> 0 ";

            using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
            using (IDataReader rdr = database.ExecuteReader(query, ConfigurationFile.Current.Settings["systemSettings"]["NodeID"].ValueAs<Guid>()))
            {
                while (rdr.Read())
                {
                    m_configuredCalculations.Add(new PowerCalculation
                    {
                        PowerCalculationID = rdr.GetInt32(0),
                        CircuitDescription = rdr.GetString(1),
                        VoltageAngleSignalID = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[2].ToString())),
                        VoltageMagnitudeSignalID = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[3].ToString())),
                        CurrentAngleSignalID = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[4].ToString())),
                        CurrentMagnitudeSignalID = MeasurementKey.LookUpBySignalID(Guid.Parse(rdr[5].ToString())),
                        ActivePowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[6].ToString()), outputMeasurements),
                        ReactivePowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[7].ToString()), outputMeasurements),
                        ApparentPowerOutputMeasurement = AddOutputMeasurement(Guid.Parse(rdr[8].ToString()), outputMeasurements)
                    });
                }
            }

            if (m_configuredCalculations.Any())
                InputMeasurementKeys = m_configuredCalculations.SelectMany(pc => new[] {pc.CurrentAngleSignalID, pc.CurrentMagnitudeSignalID, pc.VoltageAngleSignalID, pc.VoltageMagnitudeSignalID}).ToArray();
            else
                throw new InvalidOperationException("Skipped initialization of power calculator: no defined power calculations...");

            if (outputMeasurements.Any())
                OutputMeasurements = outputMeasurements.ToArray();

            Dictionary<string, string> settings = Settings;
            string setting;

            if (settings.TryGetValue("AlwaysProduceResult", out setting))
                AlwaysProduceResult = setting.ParseBoolean();

            if (settings.TryGetValue("ApplySqrt3Adjustment", out setting))
                ApplySqrt3Adjustment = setting.ParseBoolean();

            if (settings.TryGetValue("RemoveSqrt3Adjustment", out setting))
                RemoveSqrt3Adjustment = setting.ParseBoolean();

            if (settings.TryGetValue("EnableTemporalProcessing", out setting))
                EnableTemporalProcessing = setting.ParseBoolean();
        }