using System.Diagnostics;
using SSPCTester.Devices.Interfaces;
namespace SSPCTester.Logic.Testing;
/// 基础通断测试的统一判定规则。
public static class BasicTestCriteria
{
public const double OnVoltageThreshold = 1.0;
public const double OffVoltageThreshold = 0.5;
public const double CurrentPresentThreshold = 0.001;
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) =>
HasVoltageData(voltage) && !HasCurrentData(current);
///
/// 等待关状态稳定。连续多次满足“电压有数据、电流无数据”才确认关断,避免旧帧和瞬时噪声造成误判。
///
public static async Task WaitForStableOffAsync(
ISspc sspc,
int channel,
CancellationToken ct = default)
{
await Task.Delay(OffInitialDelayMs, ct).ConfigureAwait(false);
var stopwatch = Stopwatch.StartNew();
int stableSamples = 0;
ChannelMeasurement? latest = null;
while (stopwatch.ElapsedMilliseconds < OffSettleTimeoutMs)
{
latest = await sspc.ReadMeasurementAsync(channel, ct).ConfigureAwait(false);
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 sspc.ReadMeasurementAsync(channel, ct).ConfigureAwait(false);
return new OffStateResult(false, latest, stopwatch.Elapsed);
}
}
public sealed record OffStateResult(
bool IsStableOff,
ChannelMeasurement Measurement,
TimeSpan Elapsed);