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();

            // If the breaker currents are defined for breaker-and-a-half or ring bus configurations,
            // skip this data group so that timing is only applied to the breaker currents
            if (breakerNumbers.Count > 1 && breakerNumbers.Any(num => m_breakerCurrents.Contains(num)))
            {
                return;
            }

            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, m_systemFrequency, 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);

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

                    m_breakerOperations.Add(Tuple.Create(CreateEventKey(dataGroup), breakerOperationRow));
                }
            }
        }
Example #2
0
        private double GetMaxTiming(PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming)
        {
            if (!aPhaseTiming.IsValid)
            {
                return(double.NaN);
            }

            if (!bPhaseTiming.IsValid)
            {
                return(double.NaN);
            }

            if (!cPhaseTiming.IsValid)
            {
                return(double.NaN);
            }

            return(Common.Max(aPhaseTiming.Timing, bPhaseTiming.Timing, cPhaseTiming.Timing));
        }
Example #3
0
        private double GetMaxTiming(BreakerTiming breakerTiming, PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming)
        {
            if (!aPhaseTiming.IsValid)
            {
                return(breakerTiming.Timing);
            }

            if (!bPhaseTiming.IsValid)
            {
                return(breakerTiming.Timing);
            }

            if (!cPhaseTiming.IsValid)
            {
                return(breakerTiming.Timing);
            }

            return(Common.Max(aPhaseTiming.Timing, bPhaseTiming.Timing, cPhaseTiming.Timing));
        }
Example #4
0
        private string GetLatestPhase(PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming)
        {
            int an;
            int bn;
            int cn;

            if (!aPhaseTiming.IsValid)
            {
                return("None");
            }

            if (!bPhaseTiming.IsValid)
            {
                return("None");
            }

            if (!cPhaseTiming.IsValid)
            {
                return("None");
            }

            an = aPhaseTiming.TimeCleared.Index;
            bn = bPhaseTiming.TimeCleared.Index;
            cn = cPhaseTiming.TimeCleared.Index;

            if (an >= bn && an >= cn)
            {
                return("AN");
            }

            if (bn >= an && bn >= cn)
            {
                return("BN");
            }

            return("CN");
        }
Example #5
0
        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);
        }
Example #6
0
        private BreakerOperation GetBreakerOperation(AdoDataConnection connection, int eventID, string breakerNumber, BreakerTiming breakerTiming, PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming)
        {
            TableOperations <Phase> phaseTable = new TableOperations <Phase>(connection);
            TableOperations <openXDA.Model.BreakerOperationType> breakerOperationTypeTable = new TableOperations <openXDA.Model.BreakerOperationType>(connection);

            double maxTiming          = GetMaxTiming(breakerTiming, aPhaseTiming, bPhaseTiming, cPhaseTiming);
            string phase              = GetLatestPhase(aPhaseTiming, bPhaseTiming, cPhaseTiming);
            BreakerOperationType type = GetBreakerOperationType(maxTiming, breakerTiming.Speed);

            return(new BreakerOperation()
            {
                EventID = eventID,
                PhaseID = phaseTable.GetOrAdd(phase).ID,
                BreakerOperationTypeID = breakerOperationTypeTable.GetOrAdd(type.ToString()).ID,
                BreakerNumber = breakerNumber,
                TripCoilEnergized = breakerTiming.TimeEnergized.Time,
                StatusBitSet = breakerTiming.IsValid ? breakerTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                StatusBitChatter = breakerTiming.StatusChatter,
                APhaseCleared = aPhaseTiming.IsValid ? aPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                BPhaseCleared = bPhaseTiming.IsValid ? bPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                CPhaseCleared = cPhaseTiming.IsValid ? cPhaseTiming.TimeCleared.Time : breakerTiming.TimeEnergized.Time,
                BreakerTiming = NotNaN(maxTiming),
                StatusTiming = NotNaN(breakerTiming.Timing),
                APhaseBreakerTiming = NotNaN(aPhaseTiming.Timing),
                BPhaseBreakerTiming = NotNaN(bPhaseTiming.Timing),
                CPhaseBreakerTiming = NotNaN(cPhaseTiming.Timing),
                DcOffsetDetected = (aPhaseTiming.DcOffsetDetected || bPhaseTiming.DcOffsetDetected || cPhaseTiming.DcOffsetDetected),
                BreakerSpeed = NotNaN(breakerTiming.Speed)
            });
        }
Example #7
0
        private void IdentifyBreakerOperations(AdoDataConnection connection, FileGroup fileGroup, DataGroup dataGroup, VIDataGroup viDataGroup, VICycleDataGroup viCycleDataGroup)
        {
            TableOperations <Event>            eventTable            = new TableOperations <Event>(connection);
            TableOperations <BreakerChannel>   breakerChannelTable   = new TableOperations <BreakerChannel>(connection);
            TableOperations <BreakerOperation> breakerOperationTable = new TableOperations <BreakerOperation>(connection);

            List <int> channelIDs = dataGroup.DataSeries
                                    .Select(dataSeries => dataSeries.SeriesInfo.ChannelID)
                                    .Distinct()
                                    .ToList();

            if (channelIDs.Count == 0)
            {
                return;
            }

            List <string> breakerNumbers = breakerChannelTable
                                           .QueryRecordsWhere($"ChannelID IN ({string.Join(",", channelIDs)})")
                                           .Select(breakerChannel => breakerChannel.BreakerNumber)
                                           .Distinct()
                                           .ToList();

            // If the breaker currents are defined for breaker-and-a-half or ring bus configurations,
            // skip this data group so that timing is only applied to the breaker currents
            if (breakerNumbers.Count > 1 && breakerNumbers.Any(num => m_breakerCurrents.Contains(num)))
            {
                return;
            }

            Event evt = eventTable.GetEvent(fileGroup, dataGroup);

            if ((object)evt == null)
            {
                return;
            }

            foreach (string breakerNumber in breakerNumbers)
            {
                double breakerSpeed = connection.ExecuteScalar(double.NaN, "SELECT Speed FROM Breaker WHERE AssetKey = {0}", breakerNumber.TrimStart('0'));

                Func <DataSeries, bool> digitalFilter = dataSeries =>
                {
                    int channelID = dataSeries.SeriesInfo.ChannelID;

                    RecordRestriction recordRestriction =
                        new RecordRestriction("ChannelID = {0}", channelID) &
                        new RecordRestriction("BreakerNumber = {0}", breakerNumber);

                    int breakerChannelCount = breakerChannelTable.QueryRecordCount(recordRestriction);

                    return(breakerChannelCount > 0);
                };

                List <DataSeries> breakerDigitals = dataGroup.DataSeries
                                                    .Where(dataSeries => dataSeries.SeriesInfo.Channel.MeasurementType.Name == "Digital")
                                                    .Where(digitalFilter)
                                                    .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> tripCoilEnergizedTriggers = Range <XValue> .MergeAllOverlapping(tripCoilEnergizedChannels.SelectMany(FindTCERanges))
                                                          .Select(range => range.Start)
                                                          .ToList();

                foreach (XValue tripCoilEnergizedTrigger in tripCoilEnergizedTriggers)
                {
                    BreakerTiming breakerTiming = new BreakerTiming(tripCoilEnergizedTrigger, breakerStatusChannel, m_systemFrequency, breakerSpeed, m_breakerSettings.MinWaitBeforeReclose);

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

                    BreakerOperation breakerOperation = GetBreakerOperation(connection, evt.ID, breakerNumber, breakerTiming, aPhaseTiming, bPhaseTiming, cPhaseTiming);
                    breakerOperationTable.AddNewRecord(breakerOperation);
                }
            }
        }