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; /// /// 开启与关断曲线测试:高速采集 + 计算 1.1-1.6 指标。 /// public sealed class CurveTest : ITestModule { private readonly DaqOptions _daqOpts; private readonly Action? _onCurveReady; public CurveTest(IOptions options, Action? onCurveReady = null) { _daqOpts = options.Value.Daq; _onCurveReady = onCurveReady; } public string Name => "开启与关断曲线"; public async Task RunAsync(TestContext ctx, IProgress 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 { } } } } }