138 lines
5.3 KiB
C#
138 lines
5.3 KiB
C#
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using CommunityToolkit.Mvvm.ComponentModel;
|
||
using CommunityToolkit.Mvvm.Input;
|
||
using HC_APTBS.Services;
|
||
|
||
namespace HC_APTBS.ViewModels.Dialogs
|
||
{
|
||
/// <summary>
|
||
/// ViewModel for the WKlineErrors dialog.
|
||
///
|
||
/// <para>
|
||
/// Displays the raw DTC (Diagnostic Trouble Code) text returned by the VP44 ECU
|
||
/// over K-Line and provides commands to read or clear fault codes.
|
||
/// </para>
|
||
/// </summary>
|
||
public sealed partial class KlineErrorsViewModel : ObservableObject
|
||
{
|
||
// ── Services ──────────────────────────────────────────────────────────────
|
||
|
||
private readonly IKwpService _kwp;
|
||
private readonly IConfigurationService _config;
|
||
|
||
// ── Constructor ───────────────────────────────────────────────────────────
|
||
|
||
/// <summary>Initialises the ViewModel and shows the initially known error text.</summary>
|
||
public KlineErrorsViewModel(
|
||
IKwpService kwpService,
|
||
IConfigurationService configService,
|
||
string initialErrors = "")
|
||
{
|
||
_kwp = kwpService;
|
||
_config = configService;
|
||
ErrorText = initialErrors;
|
||
|
||
_kwp.ProgressChanged += OnProgress;
|
||
}
|
||
|
||
// ── Properties ────────────────────────────────────────────────────────────
|
||
|
||
/// <summary>Raw DTC string returned by the ECU, shown in the text box.</summary>
|
||
[ObservableProperty] private string _errorText = string.Empty;
|
||
|
||
/// <summary>True while a K-Line read or clear operation is in progress.</summary>
|
||
[ObservableProperty]
|
||
[NotifyCanExecuteChangedFor(nameof(ReadErrorsCommand))]
|
||
[NotifyCanExecuteChangedFor(nameof(ClearErrorsCommand))]
|
||
private bool _isBusy;
|
||
|
||
/// <summary>Progress percentage (0–100) for the current K-Line operation.</summary>
|
||
[ObservableProperty] private int _progressPercent;
|
||
|
||
/// <summary>Verbose status message for the current K-Line operation.</summary>
|
||
[ObservableProperty] private string _progressMessage = string.Empty;
|
||
|
||
// ── Commands ──────────────────────────────────────────────────────────────
|
||
|
||
/// <summary>Reads the current fault codes from the ECU.</summary>
|
||
[RelayCommand(CanExecute = nameof(CanOperate))]
|
||
private async Task ReadErrorsAsync()
|
||
{
|
||
string? port = GetPort();
|
||
if (port == null) return;
|
||
|
||
IsBusy = true;
|
||
try
|
||
{
|
||
ErrorText = await _kwp.ReadFaultCodesAsync(port);
|
||
}
|
||
finally
|
||
{
|
||
IsBusy = false;
|
||
ProgressPercent = 0;
|
||
ProgressMessage = string.Empty;
|
||
}
|
||
}
|
||
|
||
/// <summary>Clears fault codes on the ECU, then reads back the updated list.</summary>
|
||
[RelayCommand(CanExecute = nameof(CanOperate))]
|
||
private async Task ClearErrorsAsync()
|
||
{
|
||
string? port = GetPort();
|
||
if (port == null) return;
|
||
|
||
IsBusy = true;
|
||
try
|
||
{
|
||
ErrorText = await _kwp.ClearFaultCodesAsync(port);
|
||
// Re-read after clearing to confirm
|
||
ErrorText = await _kwp.ReadFaultCodesAsync(port);
|
||
}
|
||
finally
|
||
{
|
||
IsBusy = false;
|
||
ProgressPercent = 0;
|
||
ProgressMessage = string.Empty;
|
||
}
|
||
}
|
||
|
||
/// <summary>Closes the dialog.</summary>
|
||
[RelayCommand]
|
||
private void Close()
|
||
{
|
||
_kwp.ProgressChanged -= OnProgress;
|
||
RequestClose?.Invoke();
|
||
}
|
||
|
||
// ── Events ────────────────────────────────────────────────────────────────
|
||
|
||
/// <summary>Raised when the dialog should close itself.</summary>
|
||
public event System.Action? RequestClose;
|
||
|
||
// ── Helpers ───────────────────────────────────────────────────────────────
|
||
|
||
private bool CanOperate() => !IsBusy;
|
||
|
||
private string? GetPort()
|
||
{
|
||
string? port = _kwp.DetectKLinePort();
|
||
if (!string.IsNullOrEmpty(port)) return port;
|
||
|
||
MessageBox.Show(
|
||
"K-Line device not found. Check that the FTDI adapter is connected.",
|
||
"K-Line Error", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
return null;
|
||
}
|
||
|
||
private void OnProgress(int pct, string msg)
|
||
{
|
||
Application.Current.Dispatcher.Invoke(() =>
|
||
{
|
||
ProgressPercent = pct;
|
||
ProgressMessage = msg;
|
||
});
|
||
}
|
||
}
|
||
}
|