using CommunityToolkit.Mvvm.ComponentModel; namespace SSPCTester.Logic.Models; /// 基础测试单通道结果。 public partial class ChannelResult : ObservableObject { [ObservableProperty] private int _channel; [ObservableProperty] private double _voltageOn; [ObservableProperty] private double _currentOn; [ObservableProperty] private double _voltageOff; [ObservableProperty] private TestStatus _status = TestStatus.Untested; } /// 曲线测试单通道结果(覆盖指标 1.1-1.6)。 public partial class CurveResultRow : ObservableObject { [ObservableProperty] private int _channel; /// 开启时间(ms)。 [ObservableProperty] private double _onTimeMs; /// 上升时间(ms)。 [ObservableProperty] private double _riseTimeMs; /// 关闭时间(ms)。 [ObservableProperty] private double _offTimeMs; /// 下降时间(ms)。 [ObservableProperty] private double _fallTimeMs; [ObservableProperty] private string? _risingWaveformPath; [ObservableProperty] private string? _fallingWaveformPath; /// 曲线显示起点(ms,null 表示全曲线)。 [ObservableProperty] private double? _viewStartMs; /// 曲线显示终点(ms,null 表示全曲线)。 [ObservableProperty] private double? _viewEndMs; [ObservableProperty] private double? _risingViewStartMs; [ObservableProperty] private double? _risingViewEndMs; [ObservableProperty] private double? _fallingViewStartMs; [ObservableProperty] private double? _fallingViewEndMs; [ObservableProperty] private TestStatus _status = TestStatus.Untested; } /// 曲线测试阈值(合格判定)。 public sealed class CurveThresholds { public double MaxOnTimeMs { get; set; } = 5.0; public double MaxRiseTimeMs { get; set; } = 3.0; public double MaxOffTimeMs { get; set; } = 5.0; public double MaxFallTimeMs { get; set; } = 3.0; } /// 功率损耗单通道结果(覆盖指标 1.7-1.10)。 public partial class PowerLossRow : ObservableObject { [ObservableProperty] private int _channel; [ObservableProperty] private double _vin; [ObservableProperty] private double _iin; [ObservableProperty] private double _vout; [ObservableProperty] private double _iout; [ObservableProperty] private double? _measuredPowerOut; [ObservableProperty] private TestStatus _status = TestStatus.Untested; public double VoltageDrop => Vin - Vout; public double PowerIn => Vin * Iin; public double CalculatedPowerOut => Vout * Iout; public double PowerOut => CalculatedPowerOut; public double PowerLossW => PowerIn - PowerOut; public double PowerLossPct => PowerIn > 0 ? (PowerIn - CalculatedPowerOut) / PowerIn * 100.0 : 0; public double EfficiencyRatio => PowerIn > 0 ? CalculatedPowerOut / PowerIn : 0; public double EfficiencyPct => PowerIn > 0 ? PowerOut / PowerIn * 100.0 : 0; public double OutputPower => PowerOut; partial void OnVinChanged(double value) => RaiseDerived(); partial void OnIinChanged(double value) => RaiseDerived(); partial void OnVoutChanged(double value) => RaiseDerived(); partial void OnIoutChanged(double value) => RaiseDerived(); partial void OnMeasuredPowerOutChanged(double? value) => RaiseDerived(); private void RaiseDerived() { OnPropertyChanged(nameof(VoltageDrop)); OnPropertyChanged(nameof(PowerIn)); OnPropertyChanged(nameof(PowerOut)); OnPropertyChanged(nameof(CalculatedPowerOut)); OnPropertyChanged(nameof(PowerLossW)); OnPropertyChanged(nameof(PowerLossPct)); OnPropertyChanged(nameof(EfficiencyRatio)); OnPropertyChanged(nameof(EfficiencyPct)); OnPropertyChanged(nameof(OutputPower)); } } /// 保护功能单项结果。 public partial class ProtectRow : ObservableObject { [ObservableProperty] private int _index; [ObservableProperty] private string _protectType = ""; [ObservableProperty] private string _trigger = ""; [ObservableProperty] private string _measuredValue = "----"; [ObservableProperty] private string _judgeMode = "人工判别"; [ObservableProperty] private double _tripTimeMs; [ObservableProperty] private TestStatus _status = TestStatus.Untested; public bool CanMeasureFromPower => ProtectType is "跳闸" or "过压" or "欠压" or "限流"; partial void OnProtectTypeChanged(string value) => OnPropertyChanged(nameof(CanMeasureFromPower)); public static string BuildMeasuredValue(string protectType, double? inputVoltage, double? inputCurrent) => protectType switch { "跳闸" when inputCurrent.HasValue => $"{inputCurrent.Value:F3} A", "过压" or "欠压" when inputVoltage.HasValue => $"{inputVoltage.Value:F3} V", "限流" when inputCurrent.HasValue => $"{inputCurrent.Value:F3} A", _ => "----" }; } /// 保护功能固定测试项与结果初始化逻辑。 public static class ProtectTestPlan { public const string ManualJudgeMode = "人工判别"; public static readonly IReadOnlyList<(string ProtectType, string Trigger)> Items = new[] { ("跳闸", "1.5×额定电流"), ("短路", "输出短路"), ("过温", "≥85℃"), ("过压", "≥32V"), ("欠压", "≤22V"), ("限流", "≥1.2A"), }; public static void EnsureRows(Project project) { var existing = project.ProtectResults .GroupBy(x => x.ProtectType) .ToDictionary(x => x.Key, x => x.First()); project.ProtectResults.Clear(); for (int i = 0; i < Items.Count; i++) { var item = Items[i]; if (!existing.TryGetValue(item.ProtectType, out var row)) { row = new ProtectRow { ProtectType = item.ProtectType, Status = TestStatus.Untested }; } row.Index = i + 1; row.ProtectType = item.ProtectType; if (string.IsNullOrWhiteSpace(row.Trigger)) row.Trigger = item.Trigger; if (string.IsNullOrWhiteSpace(row.JudgeMode)) row.JudgeMode = ManualJudgeMode; project.ProtectResults.Add(row); } RefreshMeasuredValues(project, overwriteExisting: false); } public static void RefreshMeasuredValues(Project project, bool overwriteExisting = true) { var latestPower = project.PowerResults.LastOrDefault(); foreach (var row in project.ProtectResults) { if (!overwriteExisting && !string.IsNullOrWhiteSpace(row.MeasuredValue) && row.MeasuredValue != "----") continue; row.MeasuredValue = ProtectRow.BuildMeasuredValue(row.ProtectType, latestPower?.Vin, latestPower?.Iin); } } }