using System.Diagnostics; using SSPCTester.Devices.Interfaces; namespace SSPCTester.Logic.Testing; /// Shared pass/fail rules for the basic on/off test. public static class BasicTestCriteria { public const double OnVoltageThreshold = 1.0; public const double OffVoltageThreshold = 0.3; public const double CurrentPresentThreshold = 0.001; public const double OffCurrentThreshold = 0.3; public const int SwitchSettleDelayMs = 1_000; public const int OffSettleTimeoutMs = 2_000; public const int OffInitialDelayMs = 100; public const int OffSampleIntervalMs = 100; public const int RequiredStableOffSamples = 2; public static bool IsOn(double voltage) => voltage > OnVoltageThreshold; public static bool IsOff(double voltage) => Math.Abs(voltage) < OffVoltageThreshold; public static bool HasVoltageData(double voltage) => voltage > OnVoltageThreshold; public static bool HasCurrentData(double current) => Math.Abs(current) > CurrentPresentThreshold; public static bool IsOnState(double voltage, double current) => HasVoltageData(voltage) && HasCurrentData(current); public static bool IsOffState(double voltage, double current) => IsOff(voltage) && Math.Abs(current) < OffCurrentThreshold; /// /// Waits until the channel is stably off: no voltage and no current for consecutive samples. /// public static async Task WaitForStableOffAsync( ISspc sspc, int channel, CancellationToken ct = default, Action? onSample = null, Func>? readSampleAsync = null) { await Task.Delay(OffInitialDelayMs, ct).ConfigureAwait(false); var stopwatch = Stopwatch.StartNew(); int stableSamples = 0; ChannelMeasurement? latest = null; while (stopwatch.ElapsedMilliseconds < OffSettleTimeoutMs) { latest = await ReadSampleAsync(sspc, channel, ct, readSampleAsync).ConfigureAwait(false); onSample?.Invoke(latest); stableSamples = IsOffState(latest.Voltage, latest.Current) ? stableSamples + 1 : 0; if (stableSamples >= RequiredStableOffSamples) return new OffStateResult(true, latest, stopwatch.Elapsed); await Task.Delay(OffSampleIntervalMs, ct).ConfigureAwait(false); } latest ??= await ReadSampleAsync(sspc, channel, ct, readSampleAsync).ConfigureAwait(false); onSample?.Invoke(latest); return new OffStateResult(false, latest, stopwatch.Elapsed); } private static Task ReadSampleAsync( ISspc sspc, int channel, CancellationToken ct, Func>? readSampleAsync) => readSampleAsync?.Invoke(channel, ct) ?? sspc.ReadMeasurementAsync(channel, ct); } public sealed record OffStateResult( bool IsStableOff, ChannelMeasurement Measurement, TimeSpan Elapsed);