SSPC-Tester/SSPCTester.Logic/Testing/CurveTest.cs
2026-06-30 12:10:29 +08:00

81 lines
3.8 KiB
C#

using Microsoft.Extensions.Options;
using SSPCTester.Devices.Config;
using SSPCTester.Devices.Interfaces;
using SSPCTester.Logic.Calculation;
using SSPCTester.Logic.Models;
using SSPCTester.Logic.Storage;
namespace SSPCTester.Logic.Testing;
/// <summary>
/// 开启与关断曲线测试:高速采集 + 计算 1.1-1.6 指标。
/// </summary>
public sealed class CurveTest : ITestModule
{
private readonly DaqOptions _daqOpts;
private readonly Action<int, CurveData, CurveData>? _onCurveReady;
public CurveTest(IOptions<DeviceOptions> options, Action<int, CurveData, CurveData>? onCurveReady = null)
{
_daqOpts = options.Value.Daq;
_onCurveReady = onCurveReady;
}
public string Name => "开启与关断曲线";
public async Task RunAsync(TestContext ctx, IProgress<TestProgress> progress, CancellationToken ct)
{
int n = ctx.Sspc.ChannelCount;
var th = ctx.Project.CurveThresholds;
ctx.Project.CurveResults.Clear();
for (int ch = 1; ch <= n; ch++)
{
ct.ThrowIfCancellationRequested();
var row = new CurveResultRow { Channel = ch, Status = TestStatus.Running };
ctx.Project.CurveResults.Add(row);
progress.Report(new TestProgress { ModuleName = Name, Step = ch - 1, TotalSteps = n, Message = $"采集通道 CH{ch} 开启曲线" });
try
{
await ctx.Sspc.TurnOffAsync(ch, ct).ConfigureAwait(false);
await BasicTestCriteria.WaitForStableOffAsync(ctx.Sspc, ch, ct).ConfigureAwait(false);
var request = new DaqActionCaptureRequest(_daqOpts.PreTriggerMs, _daqOpts.PostTriggerMs, true);
var risingCurve = await ctx.Daq.CaptureAroundActionAsync(
request, token => ctx.Sspc.TurnOnAsync(ch, token), ct).ConfigureAwait(false);
double vMax = CurveMetrics.EstimateVMax(risingCurve.Voltage);
row.OnTimeMs = CurveMetrics.OnTimeMs(risingCurve, vMax, 0.9);
row.RiseTimeMs = CurveMetrics.RiseTimeMs(risingCurve, vMax);
progress.Report(new TestProgress { ModuleName = Name, Step = ch, TotalSteps = n, Message = $"采集通道 CH{ch} 关断曲线" });
await Task.Delay(100, ct).ConfigureAwait(false);
var fallingCurve = await ctx.Daq.CaptureAroundActionAsync(
request with { IsRising = false },
token => ctx.Sspc.TurnOffAsync(ch, token), ct).ConfigureAwait(false);
row.OffTimeMs = CurveMetrics.OffTimeMs(fallingCurve, vMax, 0.1);
row.FallTimeMs = CurveMetrics.FallTimeMs(fallingCurve, vMax);
bool ok = row.OnTimeMs <= th.MaxOnTimeMs
&& row.RiseTimeMs <= th.MaxRiseTimeMs
&& row.OffTimeMs <= th.MaxOffTimeMs
&& row.FallTimeMs <= th.MaxFallTimeMs
&& !double.IsNaN(row.OnTimeMs) && !double.IsNaN(row.OffTimeMs);
row.Status = ok ? TestStatus.Pass : TestStatus.Fail;
row.RisingWaveformPath = await WaveformStore.SaveAsync(ctx.Project, ch, "on", risingCurve, ct);
row.FallingWaveformPath = await WaveformStore.SaveAsync(ctx.Project, ch, "off", fallingCurve, ct);
_onCurveReady?.Invoke(ch, risingCurve, fallingCurve);
progress.Report(new TestProgress { ModuleName = Name, Step = ch, TotalSteps = n, StepStatus = row.Status, Message = $"CH{ch} {row.Status}" });
}
catch
{
row.Status = TestStatus.Fail;
throw;
}
finally
{
try { await ctx.Sspc.TurnOffAsync(ch, CancellationToken.None).ConfigureAwait(false); } catch { }
}
}
}
}