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)); } } }
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)); }
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)); }
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"); }
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 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) }); }
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); } } }