Files
HC_APTBS/Services/IKwpService.cs
LucianoDev 197e9d1775 feat: redesign dashboard with Fluent KPI tiles, connection strip, and devices column
- Replace LCD-style readings with a 3×2 KPI tile grid (Fluent card surfaces, 52pt values)
- Add persistent top connection strip with horizontal chips + pump name badge
- Add elapsed test timer (DispatcherTimer, mm:ss) to Test Summary card
- Restyle Test Summary and Active Alarms with Fluent brushes/iconography
- Add Devices column (CAN / K-Line / Bench tiles) between KPI grid and test/alarms
  - Enumerates attached PCAN USB channels via PCAN_ATTACHED_CHANNELS API
  - Enumerates FTDI K-Line adapters via existing FtdiInterface helpers
  - Click to connect/disconnect; confirmation dialog when session active or test running
  - Hover tint: blue = will connect, red = will disconnect; Bench row is read-only stub
- Extend ICanService with SelectedChannel + EnumerateAttachedChannels()
- Expose IKwpService.ConnectedPort for active session device tracking
- Add DeviceRow button style with MultiDataTrigger hover colour logic
- Add 30+ new localization keys (ES + EN) for KPI labels, devices, confirmations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 22:25:00 +02:00

160 lines
8.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using HC_APTBS.Models;
namespace HC_APTBS.Services
{
/// <summary>
/// Provides KWP2000 / KW1281 diagnostics operations over the ISO K-Line
/// via an FTDI USB-to-K-Line adapter.
/// </summary>
public interface IKwpService
{
// ── Session lifecycle ─────────────────────────────────────────────────────
/// <summary>Current state of the persistent K-Line session.</summary>
KLineConnectionState KLineState { get; }
/// <summary>
/// Raised whenever the K-Line session state transitions.
/// Fires on a background thread; consumers must marshal to the UI thread.
/// </summary>
event Action<KLineConnectionState>? KLineStateChanged;
/// <summary>
/// Opens a persistent K-Line session: performs 5-baud slow-init,
/// reads ECU info, then starts a background keep-alive loop (~1 s interval).
/// </summary>
/// <param name="port">FTDI serial number or COM port identifier.</param>
/// <param name="ct">Cancellation token.</param>
Task ConnectAsync(string port, CancellationToken ct = default);
/// <summary>
/// Stops the keep-alive loop, sends EndCommunication to the ECU,
/// and disposes the FTDI interface.
/// </summary>
void Disconnect();
// ── Progress reporting ────────────────────────────────────────────────────
/// <summary>
/// Raised during long operations to report completion percentage and a status message.
/// Always marshalled to the UI thread by the implementation.
/// </summary>
event Action<int, string>? ProgressChanged;
// ── Full ECU read ─────────────────────────────────────────────────────────
/// <summary>
/// Connects to the pump ECU over K-Line and reads all available identification data,
/// fault codes, DFI value, serial number, and software versions.
/// </summary>
/// <param name="port">FTDI serial number or COM port identifier.</param>
/// <param name="pumpVersion">KWP protocol variant (0=V1, 1=V2, 2=V3/V4).</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>
/// Dictionary with keys from <see cref="HC_APTBS.Models.KlineKeys"/>.
/// The <c>result</c> key is "1" on success, "0" on failure.
/// </returns>
Task<Dictionary<string, string>> ReadAllInfoAsync(
string port, int pumpVersion, CancellationToken ct = default);
// ── DTC operations ────────────────────────────────────────────────────────
/// <summary>Reads all current diagnostic trouble codes from the ECU.</summary>
/// <param name="port">FTDI serial number or COM port identifier.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>Formatted fault code string, or "No fault codes".</returns>
Task<string> ReadFaultCodesAsync(string port, CancellationToken ct = default);
/// <summary>Clears all diagnostic trouble codes and returns the post-clear state.</summary>
/// <param name="port">FTDI serial number or COM port identifier.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>Post-clear fault code string.</returns>
Task<string> ClearFaultCodesAsync(string port, CancellationToken ct = default);
// ── DFI calibration ───────────────────────────────────────────────────────
/// <summary>Reads the current DFI calibration angle from EEPROM address 0x0044.</summary>
/// <param name="port">FTDI serial number or COM port identifier.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>DFI value in degrees as a formatted string.</returns>
Task<string> ReadDfiAsync(string port, CancellationToken ct = default);
/// <summary>
/// Writes a new DFI calibration angle to EEPROM address 0x0044.
/// </summary>
/// <param name="port">FTDI serial number or COM port identifier.</param>
/// <param name="dfi">Target DFI angle (degrees, range ±1.45°).</param>
/// <param name="version">KWP protocol variant (selects the authentication password).</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>Verified DFI value read back from EEPROM after the write.</returns>
Task<string> WriteDfiAsync(
string port, float dfi, int version, CancellationToken ct = default);
/// <summary>
/// Writes DFI to EEPROM, then triggers a pump power cycle via
/// <see cref="PumpDisconnectRequested"/> / <see cref="PumpReconnectRequested"/>
/// to activate the new calibration.
/// </summary>
Task<string> WriteDfiAndRestartAsync(
string port, float dfi, int version, CancellationToken ct = default);
// ── Device detection ──────────────────────────────────────────────────────
/// <summary>
/// Enumerates connected FTDI USB devices and returns the serial number of the
/// first one found, or <see langword="null"/> if none are connected.
/// </summary>
string? DetectKLinePort();
/// <summary>
/// The FTDI serial number of the device that is currently holding an open
/// K-Line session, or <see langword="null"/> when no session is active.
/// </summary>
string? ConnectedPort { get; }
// ── Mid-read notifications ────────────────────────────────────────────
/// <summary>
/// Raised during <see cref="ReadAllInfoAsync"/> as soon as the pump identifier
/// string has been read from ROM, before the full read completes.
/// Fires on a background thread; consumers must marshal to the UI thread.
/// </summary>
event Action<string>? PumpIdentified;
/// <summary>
/// Raised during <see cref="ReadAllInfoAsync"/> when the DFI calibration
/// value has been read from EEPROM. Parameter is the DFI angle in degrees.
/// Fires on a background thread; consumers must marshal to the UI thread.
/// </summary>
event Action<double>? DfiRead;
// ── Fast immobilizer unlock ───────────────────────────────────────────────
/// <summary>
/// Attempts a fast immobilizer unlock by sending a KWP custom command
/// over an existing K-Line session. Returns <see langword="true"/> if the
/// command was acknowledged (pump already unlocked), <see langword="false"/>
/// if it was rejected or no session is active.
/// </summary>
Task<bool> TryFastUnlockAsync();
// ── Power cycle callbacks ─────────────────────────────────────────────────
/// <summary>
/// Raised when the service needs the bench to cut power to the pump
/// (e.g. after a DFI write) before reconnecting.
/// </summary>
event Action? PumpDisconnectRequested;
/// <summary>
/// Raised after <see cref="PumpDisconnectRequested"/> when the service needs
/// the bench to restore power and re-establish the K-Line session.
/// </summary>
event Action? PumpReconnectRequested;
}
}