using SSPCTester.Devices.Interfaces;
using SSPCTester.Logic.Models;
namespace SSPCTester.Logic.Testing;
/// Power loss test using UDP5080 input measurements and SSPC output measurements.
public sealed class PowerTest : ITestModule
{
private readonly IPowerSupply _power;
public PowerTest(IPowerSupply power)
{
_power = power;
}
public string Name => "功率损耗";
public int SamplesPerChannel { get; set; } = 5;
public int IntervalMs { get; set; } = 100;
public async Task RunAsync(TestContext ctx, IProgress progress, CancellationToken ct)
{
if (!_power.IsConnected) await _power.ConnectAsync(ct).ConfigureAwait(false);
if (!ctx.Load.IsConnected) await ctx.Load.ConnectAsync(ct).ConfigureAwait(false);
int n = ctx.Sspc.ChannelCount;
ctx.Project.PowerResults.Clear();
for (int ch = 1; ch <= n; ch++)
{
ct.ThrowIfCancellationRequested();
var row = new PowerLossRow { Channel = ch, Status = TestStatus.Running };
ctx.Project.PowerResults.Add(row);
progress.Report(new TestProgress { ModuleName = Name, Step = ch - 1, TotalSteps = n, Message = $"采集 CH{ch} 输入/输出两端数据" });
try
{
double sumVin = 0, sumIin = 0, sumVout = 0, sumIout = 0, sumPout = 0;
for (int s = 0; s < SamplesPerChannel; s++)
{
var input = await _power.ReadAsync(ct).ConfigureAwait(false);
var output = await ctx.Load.ReadPowerAsync(ct).ConfigureAwait(false);
double vin = input.volts;
double iin = Math.Abs(input.amps);
double vout = output.Volts;
double iout = Math.Abs(output.Amps);
double pout = output.Watts;
if (!double.IsFinite(vin) || !double.IsFinite(iin) || !double.IsFinite(vout) || !double.IsFinite(iout) || !double.IsFinite(pout))
throw new InvalidOperationException("功率损耗采样无效:请检查 UDP5080-100 电源测量与 Modbus 连接。");
sumVin += vin;
sumIin += iin;
sumVout += vout;
sumIout += iout;
sumPout += pout;
await Task.Delay(IntervalMs, ct).ConfigureAwait(false);
}
row.Vin = sumVin / SamplesPerChannel;
row.Iin = sumIin / SamplesPerChannel;
row.Vout = sumVout / SamplesPerChannel;
row.Iout = sumIout / SamplesPerChannel;
row.MeasuredPowerOut = sumPout / SamplesPerChannel;
row.Status = TestStatus.Measured;
}
catch
{
row.Status = TestStatus.Fail;
throw;
}
progress.Report(new TestProgress { ModuleName = Name, Step = ch, TotalSteps = n, StepStatus = row.Status, Message = $"CH{ch} 损耗={row.PowerLossW:F2}W 效率={row.EfficiencyPct:F1}%" });
}
}
}