8383using GSF . Parsing ;
8484using GSF . PhasorProtocols . IEEEC37_118 ;
8585using GSF . PhasorProtocols . Macrodyne ;
86+ using GSF . PhasorProtocols . SelCWS ;
8687using GSF . PhasorProtocols . SelFastMessage ;
8788using GSF . Threading ;
8889using GSF . TimeSeries ;
@@ -1460,14 +1461,14 @@ private void SharedClient_SendDataException(object sender, EventArgs<Exception>
14601461 private IClient m_commandChannel ;
14611462 private IPAddress m_receiveFromAddress ;
14621463 private IPAddress m_multicastServerAddress ;
1464+ private ReplayTimer m_replayTimer ;
14631465 private PrecisionInputTimer m_inputTimer ;
14641466 private ShortSynchronizedOperation m_readNextBuffer ;
14651467 private SharedTimer m_rateCalcTimer ;
14661468 private IConfigurationFrame m_configurationFrame ;
14671469 private CheckSumValidationFrameTypes m_checkSumValidationFrameTypes ;
14681470 private long m_dataStreamStartTime ;
14691471 private long m_missingFramesOverflow ;
1470- private long m_lastFrameReceivedTime ;
14711472 private int m_frameRateTotal ;
14721473 private int m_byteRateTotal ;
14731474 private int m_parsingExceptionCount ;
@@ -2553,11 +2554,41 @@ private void InitializeFrameParser(Dictionary<string, string> settings)
25532554 if ( settings . TryGetValue ( "calculatePhaseEstimates" , out setting ) )
25542555 selCWSParameters . CalculatePhaseEstimates = setting . ParseBoolean ( ) ;
25552556
2556- if ( settings . TryGetValue ( "frameRate" , out setting ) && ushort . TryParse ( setting , out ushort frameRate ) )
2557- selCWSParameters . FrameRate = frameRate ;
2558-
25592557 if ( settings . TryGetValue ( "nominalFrequency" , out setting ) && Enum . TryParse ( setting , true , out LineFrequency nominalFrequency ) )
25602558 selCWSParameters . NominalFrequency = nominalFrequency ;
2559+
2560+ if ( settings . TryGetValue ( "calculationFrameRate" , out setting ) && ushort . TryParse ( setting , out ushort calculationFrameRate ) )
2561+ selCWSParameters . CalculationFrameRate = calculationFrameRate ;
2562+
2563+ if ( settings . TryGetValue ( "repeatLastCalculatedValueWhenDownSampling" , out setting ) )
2564+ selCWSParameters . RepeatLastCalculatedValueWhenDownSampling = setting . ParseBoolean ( ) ;
2565+
2566+ if ( settings . TryGetValue ( "referenceChannel" , out setting ) && Enum . TryParse ( setting , true , out PhaseChannel referenceChannel ) )
2567+ selCWSParameters . ReferenceChannel = referenceChannel ;
2568+
2569+ if ( settings . TryGetValue ( "targetCycles" , out setting ) && int . TryParse ( setting , out int targetCycles ) )
2570+ selCWSParameters . TargetCycles = targetCycles ;
2571+
2572+ if ( settings . TryGetValue ( "publishAnglesTauSeconds" , out setting ) && double . TryParse ( setting , out double publishAnglesTauSeconds ) )
2573+ selCWSParameters . PublishAnglesTauSeconds = publishAnglesTauSeconds ;
2574+
2575+ if ( settings . TryGetValue ( "publishMagnitudesTauSeconds" , out setting ) && double . TryParse ( setting , out double publishMagnitudesTauSeconds ) )
2576+ selCWSParameters . PublishMagnitudesTauSeconds = publishMagnitudesTauSeconds ;
2577+
2578+ if ( settings . TryGetValue ( "publishFrequencyTauSeconds" , out setting ) && double . TryParse ( setting , out double publishFrequencyTauSeconds ) )
2579+ selCWSParameters . PublishFrequencyTauSeconds = publishFrequencyTauSeconds ;
2580+
2581+ if ( settings . TryGetValue ( "publishRocofTauSeconds" , out setting ) && double . TryParse ( setting , out double publishRocofTauSeconds ) )
2582+ selCWSParameters . PublishRocofTauSeconds = publishRocofTauSeconds ;
2583+
2584+ if ( settings . TryGetValue ( "sampleFrequencyTauSeconds" , out setting ) && double . TryParse ( setting , out double sampleFrequencyTauSeconds ) )
2585+ selCWSParameters . SampleFrequencyTauSeconds = sampleFrequencyTauSeconds ;
2586+
2587+ if ( settings . TryGetValue ( "sampleRocofTauSeconds" , out setting ) && double . TryParse ( setting , out double sampleRocofTauSeconds ) )
2588+ selCWSParameters . SampleRocofTauSeconds = sampleRocofTauSeconds ;
2589+
2590+ if ( settings . TryGetValue ( "recalculationCycles" , out setting ) && int . TryParse ( setting , out int recalculationCycles ) )
2591+ selCWSParameters . RecalculationCycles = recalculationCycles ;
25612592 }
25622593 break ;
25632594 default :
@@ -3574,19 +3605,12 @@ private long MaintainCapturedFrameReplayTiming()
35743605 {
35753606 if ( m_inputTimer is null )
35763607 {
3577- if ( m_lastFrameReceivedTime > 0L )
3578- {
3579- // To maintain timing on "frames per second", we wait for defined frame rate interval
3580- double sleepTime = 1.0D / m_definedFrameRate - ( DateTime . UtcNow . Ticks - m_lastFrameReceivedTime ) / ( double ) Ticks . PerSecond ;
3581-
3582- // Thread sleep time is a minimum suggested sleep time depending on system activity, when not using high-resolution
3583- // input timer we assume getting close is good enough
3584- if ( sleepTime > 0.0D )
3585- Thread . Sleep ( ( int ) ( sleepTime * 1000.0D ) ) ;
3586- }
3608+ if ( m_replayTimer ? . DefinedFrameRate != m_definedFrameRate )
3609+ m_replayTimer = new ReplayTimer ( m_definedFrameRate ) ;
35873610
3588- m_lastFrameReceivedTime = DateTime . UtcNow . Ticks ;
3589- return Ticks . AlignToMillisecondDistribution ( m_lastFrameReceivedTime , m_definedFrameRate ) . Value ;
3611+ m_replayTimer . WaitNext ( ) ;
3612+
3613+ return Ticks . AlignToMillisecondDistribution ( DateTime . UtcNow . Ticks , m_definedFrameRate ) . Value ;
35903614 }
35913615
35923616 // When high resolution input timing is requested, we only need to wait for the next signal...
@@ -3608,7 +3632,7 @@ private void m_frameParser_ReceivedChannelFrame(object sender, EventArgs<IChanne
36083632 frame . Timestamp = Ticks . AlignToMillisecondDistribution ( DateTime . UtcNow . Ticks , m_definedFrameRate ) ;
36093633
36103634 // Keep reading file data
3611- if ( m_transportProtocol == TransportProtocol . File && QueuedOutputs < 2 && QueuedBuffers < 10 )
3635+ if ( m_transportProtocol == TransportProtocol . File && ( QueuedOutputs < 2 || QueuedBuffers < 10 ) )
36123636 m_readNextBuffer ? . RunOnceAsync ( ) ;
36133637
36143638 if ( ReceivedChannelFrame is not null && e . Argument2 )
0 commit comments