private MeterData.BreakerOperationRow GetBreakerOperationRow(string breakerNumber, BreakerTiming breakerTiming, PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming)
        {
            double maxTiming          = GetMaxTiming(aPhaseTiming, bPhaseTiming, cPhaseTiming);
            string phase              = GetLatestPhase(aPhaseTiming, bPhaseTiming, cPhaseTiming);
            BreakerOperationType type = GetBreakerOperationType(maxTiming, breakerTiming.Speed);

            MeterData.BreakerOperationRow breakerOperationRow = m_breakerOperationTable.NewBreakerOperationRow();

            breakerOperationRow.PhaseID = m_phaseLookup.GetOrAdd(phase, name => new Phase()
            {
                Name = name, Description = name
            }).ID;
            breakerOperationRow.BreakerOperationTypeID = s_breakerOperationTypeLookup[type];
            breakerOperationRow.BreakerNumber          = breakerNumber;
            breakerOperationRow.TripCoilEnergized      = breakerTiming.TimeEnergized.Time;
            breakerOperationRow.StatusBitSet           = breakerTiming.IsValid ? breakerTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time;
            breakerOperationRow.APhaseCleared          = aPhaseTiming.IsValid ? aPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time;
            breakerOperationRow.BPhaseCleared          = bPhaseTiming.IsValid ? bPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time;
            breakerOperationRow.CPhaseCleared          = cPhaseTiming.IsValid ? cPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time;
            breakerOperationRow.BreakerTiming          = NotNaN(maxTiming);
            breakerOperationRow.APhaseBreakerTiming    = NotNaN(aPhaseTiming.Timing);
            breakerOperationRow.BPhaseBreakerTiming    = NotNaN(bPhaseTiming.Timing);
            breakerOperationRow.CPhaseBreakerTiming    = NotNaN(cPhaseTiming.Timing);
            breakerOperationRow.BreakerSpeed           = NotNaN(breakerTiming.Speed);

            return(breakerOperationRow);
        }
        private void IdentifyBreakerOperations(DataGroup dataGroup, VIDataGroup viDataGroup, VICycleDataGroup viCycleDataGroup)
        {
            List <string> breakerNumbers = dataGroup.DataSeries
                                           .SelectMany(dataSeries => dataSeries.SeriesInfo.Channel.BreakerChannels)
                                           .Select(breakerChannel => breakerChannel.BreakerNumber)
                                           .Distinct()
                                           .ToList();

            foreach (string breakerNumber in breakerNumbers)
            {
                double breakerSpeed = ConvertBreakerSpeed(m_dbAdapterContainer.Connection.ExecuteScalar("SELECT BreakerSpeed FROM MaximoBreaker WHERE BreakerNum = @breakerNumber", breakerNumber));

                List <DataSeries> breakerDigitals = dataGroup.DataSeries
                                                    .Where(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementType.Name == "Digital")
                                                    .Where(dataSeries => dataSeries.SeriesInfo.Channel.BreakerChannels.Any(breakerChannel => breakerChannel.BreakerNumber == breakerNumber))
                                                    .ToList();

                List <DataSeries> tripCoilEnergizedChannels = breakerDigitals
                                                              .Where(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name == "TCE")
                                                              .ToList();

                DataSeries breakerStatusChannel = breakerDigitals
                                                  .FirstOrDefault(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementCharacteristic.Name == "BreakerStatus");

                List <XValue> breakerOperations = Range <XValue> .MergeAllOverlapping(tripCoilEnergizedChannels.SelectMany(FindTCERanges))
                                                  .Select(range => range.Start)
                                                  .ToList();

                foreach (XValue breakerOperation in breakerOperations)
                {
                    BreakerTiming breakerTiming = new BreakerTiming(breakerOperation, breakerStatusChannel, breakerSpeed);

                    PhaseTiming aPhaseTiming = new PhaseTiming(viDataGroup.IA, viCycleDataGroup.IA, breakerTiming, m_systemFrequency, m_breakerSettings.OpenBreakerThreshold);
                    PhaseTiming bPhaseTiming = new PhaseTiming(viDataGroup.IB, viCycleDataGroup.IB, breakerTiming, m_systemFrequency, m_breakerSettings.OpenBreakerThreshold);
                    PhaseTiming cPhaseTiming = new PhaseTiming(viDataGroup.IC, viCycleDataGroup.IC, breakerTiming, m_systemFrequency, m_breakerSettings.OpenBreakerThreshold);

                    MeterData.BreakerOperationRow breakerOperationRow = GetBreakerOperationRow(breakerNumber, breakerTiming, aPhaseTiming, bPhaseTiming, cPhaseTiming);

                    m_breakerOperations.Add(Tuple.Create(CreateEventKey(dataGroup), breakerOperationRow));
                }
            }
        }