From 50fb647f91e21f59e1071a6722af5490fd4f6a83 Mon Sep 17 00:00:00 2001 From: Ari Sulistiono Date: Sun, 18 Oct 2026 06:13:03 +0700 Subject: [PATCH 1/7] fix(scope): reset peak hold on stream/unit changes and large amplitude drops to prevent flat-line startup --- .../Controls/WaveformPanelControl.cs | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/src/ProcessBus.App.Wpf/Controls/WaveformPanelControl.cs b/src/ProcessBus.App.Wpf/Controls/WaveformPanelControl.cs index d3870ec8..5164b09a 100644 --- a/src/ProcessBus.App.Wpf/Controls/WaveformPanelControl.cs +++ b/src/ProcessBus.App.Wpf/Controls/WaveformPanelControl.cs @@ -41,6 +41,8 @@ public sealed class WaveformPanelControl : FrameworkElement private double _currentAutoPeak; private DateTime _voltagePeakUpdatedUtc = DateTime.MinValue; private DateTime _currentPeakUpdatedUtc = DateTime.MinValue; + private string? _voltageUnit; + private string? _currentUnit; private const double AutoScaleHeadroom = 1.28; private const double AutoScaleSmoothing = 0.18; // Steady-state deadband: the observed window peak jitters a little every cycle, and an @@ -64,6 +66,15 @@ public WaveformPanelControl() typeof(WaveformPanelControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender)); + // A reused WPF control must never carry a raw-count peak range into a + // different SV publisher. Stream identity is cheap state, not packet work. + public static readonly DependencyProperty StreamKeyProperty = + DependencyProperty.Register( + nameof(StreamKey), typeof(string), typeof(WaveformPanelControl), + new FrameworkPropertyMetadata(string.Empty, + FrameworkPropertyMetadataOptions.AffectsRender, + static (d, _) => ((WaveformPanelControl)d).ResetScaleState())); + public static readonly DependencyProperty ShowModeProperty = DependencyProperty.Register( nameof(ShowMode), @@ -112,6 +123,42 @@ public WaveformSnapshot? Snapshot set => SetValue(SnapshotProperty, value); } + public string StreamKey + { + get => (string)GetValue(StreamKeyProperty); + set => SetValue(StreamKeyProperty, value); + } + + private void ResetScaleState() + { + _voltageAutoPeak = 0; + _currentAutoPeak = 0; + _voltagePeakUpdatedUtc = DateTime.MinValue; + _currentPeakUpdatedUtc = DateTime.MinValue; + _voltageUnit = null; + _currentUnit = null; + } + + private void ResetLaneScaleWhenUnitsChange(bool isVoltage, string unit) + { + if (isVoltage) + { + if (string.Equals(_voltageUnit, unit, StringComparison.OrdinalIgnoreCase)) + return; + _voltageUnit = unit; + _voltageAutoPeak = 0; + _voltagePeakUpdatedUtc = DateTime.MinValue; + } + else + { + if (string.Equals(_currentUnit, unit, StringComparison.OrdinalIgnoreCase)) + return; + _currentUnit = unit; + _currentAutoPeak = 0; + _currentPeakUpdatedUtc = DateTime.MinValue; + } + } + public string ShowMode { get => (string)GetValue(ShowModeProperty); @@ -355,6 +402,7 @@ private double ResolveLaneAmplitudeMax(LaneDefinition lane, IReadOnlyList= _voltageAutoPeak || (now - _voltagePeakUpdatedUtc).TotalSeconds > PeakHoldSeconds) + // A 1000× counts-to-V conversion (or sudden real magnitude change) + // must not be hidden as a flat line for the entire hold timeout. + if (_voltageAutoPeak <= 0 || + targetPeak < _voltageAutoPeak * 0.25 || + targetPeak >= _voltageAutoPeak || + (now - _voltagePeakUpdatedUtc).TotalSeconds > PeakHoldSeconds) { _voltageAutoPeak = targetPeak; _voltagePeakUpdatedUtc = now; @@ -459,7 +512,10 @@ private double ResolvePeakHoldScale(bool isVoltage, double targetPeak) return Math.Max(_voltageAutoPeak, 1.0); } - if (targetPeak >= _currentAutoPeak || (now - _currentPeakUpdatedUtc).TotalSeconds > PeakHoldSeconds) + if (_currentAutoPeak <= 0 || + targetPeak < _currentAutoPeak * 0.25 || + targetPeak >= _currentAutoPeak || + (now - _currentPeakUpdatedUtc).TotalSeconds > PeakHoldSeconds) { _currentAutoPeak = targetPeak; _currentPeakUpdatedUtc = now; From 3e56e1d37fbef8cc2b19fcc494edf72ff7ea0419 Mon Sep 17 00:00:00 2001 From: Ari Sulistiono Date: Sun, 18 Oct 2026 06:15:09 +0700 Subject: [PATCH 2/7] fix(ui): remove redundant 2-cycle chip, space stream rows and reset scope when publisher changes --- src/ProcessBus.App.Wpf/MainWindow.xaml | 47 +++----------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/src/ProcessBus.App.Wpf/MainWindow.xaml b/src/ProcessBus.App.Wpf/MainWindow.xaml index e5ff7c6a..eb83d1ad 100644 --- a/src/ProcessBus.App.Wpf/MainWindow.xaml +++ b/src/ProcessBus.App.Wpf/MainWindow.xaml @@ -922,6 +922,7 @@ - - + + - - - - - - - - - - - - - - - - - - - +