feat: chart grid, pressure tolerance bands, QDelivery RPM normalization, pump page polish

Charts
- Add faint background grid (0.75px, #E0E0E0) to all live charts; matches PDF report style
- Show min/max tolerance bands on P1/P2 pressure charts during test runs (previously only Q-Delivery/Q-Over)
- Broaden BenchService.ToleranceUpdated to fire for every phase receive; UI routes by name
- Clear P1/P2 traces on PhaseChanged alongside Delivery/Over

CAN
- Normalize QDelivery flow rate to 1000 RPM reference before IIR filter so RPM spikes are low-pass filtered with flow-rate transients (matches old_source behavior)

Pump page
- Reorder columns: identification left, commands center, live data right
- PreIn control always visible; disabled when pump lacks pre-injection (rename IsPreInVisible -> IsPreInAvailable)
- Swap value/label order in command cards
- Remove redundant KlineErrors row from identification card

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 21:42:30 +02:00
parent 69bfda54e1
commit d9775b48be
8 changed files with 80 additions and 39 deletions

View File

@@ -252,6 +252,8 @@ namespace HC_APTBS.ViewModels
// Clear real-time plot traces at each new phase boundary.
FlowmeterChart.Delivery.Clear();
FlowmeterChart.Over.Clear();
BenchPage.PressureTrace.P1.Clear();
BenchPage.PressureTrace.P2.Clear();
});
_bench.PhaseTimerTick += (section, remaining, total) => App.Current.Dispatcher.Invoke(
() => TestPanel.ApplyPhaseTimerTick(section, remaining, total));
@@ -269,6 +271,10 @@ namespace HC_APTBS.ViewModels
{
TestPanel.UpdateLiveIndicator(paramName, value);
FlowmeterChart.SetTolerance(paramName, value, tolerance);
if (paramName == BenchParameterNames.Pressure)
BenchPage.PressureTrace.P1.SetTolerance(value, tolerance);
else if (paramName == BenchParameterNames.AnalogSensor2)
BenchPage.PressureTrace.P2.SetTolerance(value, tolerance);
});
_bench.MeasurementSampled += (name, value) => App.Current.Dispatcher.Invoke(() =>
@@ -277,6 +283,10 @@ namespace HC_APTBS.ViewModels
FlowmeterChart.Delivery.AddValue(value);
else if (name == BenchParameterNames.QOver)
FlowmeterChart.Over.AddValue(value);
else if (name == BenchParameterNames.Pressure)
BenchPage.PressureTrace.P1.AddValue(value);
else if (name == BenchParameterNames.AnalogSensor2)
BenchPage.PressureTrace.P2.AddValue(value);
});
_bench.EmergencyStopTriggered += reason => App.Current.Dispatcher.Invoke(() =>
{
@@ -329,7 +339,7 @@ namespace HC_APTBS.ViewModels
_can.RegisterPumpMessageIds(GetReceiveMessageIds(pump.ParametersById));
// Configure pump control sliders.
PumpControl.IsPreInVisible = pump.HasPreInjection;
PumpControl.IsPreInAvailable = pump.HasPreInjection;
PumpControl.IsEnabled = true;
PumpControl.Reset();

View File

@@ -64,7 +64,7 @@ namespace HC_APTBS.ViewModels
// ── Visibility / enablement ───────────────────────────────────────────────
/// <summary>True when the current pump supports pre-injection.</summary>
[ObservableProperty] private bool _isPreInVisible;
[ObservableProperty] private bool _isPreInAvailable;
/// <summary>True when a pump is selected and CAN is connected.</summary>
[ObservableProperty] private bool _isEnabled;

View File

@@ -79,7 +79,8 @@ namespace HC_APTBS.ViewModels
new Axis
{
AnimationsSpeed = TimeSpan.Zero,
MinLimit = 0
MinLimit = 0,
SeparatorsPaint = new SolidColorPaint(new SKColor(224, 224, 224), 0.75f)
}
};
}