private BreakerOperationRow GetBreakerOperationRow(string breakerNumber, BreakerTiming breakerTiming, PhaseTiming aPhaseTiming, PhaseTiming bPhaseTiming, PhaseTiming cPhaseTiming) { double maxTiming = GetMaxTiming(breakerTiming, aPhaseTiming, bPhaseTiming, cPhaseTiming); string phase = GetLatestPhase(aPhaseTiming, bPhaseTiming, cPhaseTiming); BreakerOperationType type = GetBreakerOperationType(maxTiming, breakerTiming.Speed); 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.StatusTiming = NotNaN(breakerTiming.Timing); 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(); // 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)); } } }
public PhaseTiming(DataSeries waveform, CycleDataGroup cycleDataGroup, BreakerTiming breakerTiming, double systemFrequency, double openBreakerThreshold) { m_waveform = waveform; m_cycleDataGroup = cycleDataGroup; m_systemFrequency = systemFrequency; m_timeCleared = FindBreakerOpen(breakerTiming.TimeEnergized.Index, openBreakerThreshold); if ((object)m_timeCleared != null) { m_timing = (m_timeCleared.Time - breakerTiming.TimeEnergized.Time).TotalSeconds * systemFrequency; } else { m_timing = double.NaN; } }
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 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); } } }