feat: developer tools page, auto-test orchestrator, BIP display, tests redesign
Bundles several feature streams that have been iterating on the working tree: - Developer Tools page (Debug-only via DEVELOPER_TOOLS symbol): hosts the identification card, manual KWP write + transaction log, ROM/EEPROM dump card with progress banner and completion message, persisted custom-commands library, persisted EEPROM passwords library. New service primitives: IKwpService.SendRawCustomAsync / ReadEepromAsync / ReadRomEepromAsync. Persistence mirrors the Clients XML pattern in two new files (custom_commands.xml, eeprom_passwords.xml). - Auto-test orchestrator (IAutoTestOrchestrator + AutoTestState): linear K-Line read -> unlock -> bench-on -> test sequence with snackbar UI and progress dialog VM, gated on dashboard alarms. - BIP-STATUS display: BipDisplayViewModel + BipDisplayView, RAM read at 0x0106 via IKwpService.ReadBipStatusAsync; status definitions in BipStatusDefinition. - Tests page redesign: TestSectionCard + PhaseTileView replacing the old TestPlanView/TestRunningView/TestDoneView/TestPreconditionsView/ TestSectionView controls and their VMs. - Pump command sliders: Fluent thick-track style with overhang thumb, click-anywhere-and-drag, mouse-wheel adjustment. - Window startup: app.manifest declares PerMonitorV2 DPI awareness, MainWindow installs a WM_GETMINMAXINFO hook in OnSourceInitialized and maximizes there (after the hook is in place) so the app fits the work area exactly on any display configuration. - Misc: PercentToPixelsConverter, seed_aliases.py one-shot pump-alias importer, tools/Import-BipStatus.ps1, kline_eeprom_spec.md and dump-functions reference docs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,9 @@ namespace HC_APTBS.Models
|
||||
/// <summary>Flasher relay toggle interval (ms).</summary>
|
||||
public int FlasherIntervalMs { get; set; } = 800;
|
||||
|
||||
/// <summary>RPM trend chart update rate on the Pump page (Hz). Drives a fixed-rate timer independent of value changes.</summary>
|
||||
public int RpmChartUpdateHz { get; set; } = 15;
|
||||
|
||||
// ── PID temperature controller ────────────────────────────────────────
|
||||
|
||||
/// <summary>Proportional gain.</summary>
|
||||
@@ -119,6 +122,16 @@ namespace HC_APTBS.Models
|
||||
/// <summary>When true, the T-in temperature sensor check is bypassed.</summary>
|
||||
public bool DefaultIgnoreTin { get; set; } = true;
|
||||
|
||||
// ── Auto Test ─────────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// When true, the Dashboard "Connect & Auto Test" flow bypasses the oil-pump
|
||||
/// leak-check dialog. Operator accepts that responsibility up front by enabling
|
||||
/// this toggle. Does not affect the manual Bench page oil-pump toggle, which
|
||||
/// always shows the dialog.
|
||||
/// </summary>
|
||||
public bool AutoTestSkipsOilPumpConfirm { get; set; }
|
||||
|
||||
// ── Log rotation ──────────────────────────────────────────────────────
|
||||
|
||||
/// <summary>Number of daily log files to retain before the oldest is deleted.</summary>
|
||||
|
||||
@@ -6,10 +6,7 @@ namespace HC_APTBS.Models
|
||||
// BIP (Begin of Injection Period) status definitions.
|
||||
// Applies only to pre-injection PSG5-PI pumps (Type 2 T15xxx / Type 3 T18xxx Ford).
|
||||
// Null on standard VP44 pumps.
|
||||
//
|
||||
// Data model only in this revision: runtime polling of a BIP capture source
|
||||
// (KWP RAM read of ADR-S_BIP_HW_UW / 0x0106, or a dedicated CAN frame) is not
|
||||
// yet wired. PumpBipDefinition.Match(ushort) is the seam for future work.
|
||||
// Data source: KWP RAM read of ADR-S_BIP_HW_UW at address 0x0106 (16-bit unsigned).
|
||||
|
||||
/// <summary>
|
||||
/// One BIP-STATUS entry: a 16-bit HEX pattern matched against the captured BIP
|
||||
@@ -17,6 +14,9 @@ namespace HC_APTBS.Models
|
||||
/// </summary>
|
||||
public class BipStatusDefinition
|
||||
{
|
||||
/// <summary>Zero-based definition index (BIP-STATUS0 = 0 … BIP-STATUS7 = 7).</summary>
|
||||
public int Index { get; set; }
|
||||
|
||||
/// <summary>Whether this definition participates in pattern matching.</summary>
|
||||
public bool Enabled { get; set; } = true;
|
||||
|
||||
@@ -54,9 +54,11 @@ namespace HC_APTBS.Models
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first enabled definition whose <see cref="BipStatusDefinition.HexPattern"/>
|
||||
/// exactly equals <paramref name="value"/>, or null if none match.
|
||||
/// matches <paramref name="value"/> via bitmask semantics: all bits set in the pattern
|
||||
/// must be set in the captured word (<c>(value & pattern) == pattern</c>).
|
||||
/// Pattern 0x0000 matches any value (OK state by convention in the legacy CFG).
|
||||
/// </summary>
|
||||
public BipStatusDefinition? Match(ushort value) =>
|
||||
Bits.FirstOrDefault(b => b.Enabled && b.HexPattern == value);
|
||||
Bits.FirstOrDefault(b => b.Enabled && (value & b.HexPattern) == b.HexPattern);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,21 @@ namespace HC_APTBS.Models
|
||||
/// </summary>
|
||||
public bool NeedsUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Raised on the CAN read thread after a decoded frame causes <see cref="Value"/>
|
||||
/// to change. The decoder compares post-filter values and only fires on a real
|
||||
/// delta, so handlers that only care about state transitions do not need their own
|
||||
/// change-detection. Handlers run on the CAN read thread — they must not block and
|
||||
/// must marshal to the UI thread themselves if they touch WPF state.
|
||||
/// </summary>
|
||||
public event Action<CanBusParameter>? ValueChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes <see cref="ValueChanged"/>. Intended to be called by the CAN decoder
|
||||
/// after a value update; internal so other layers cannot raise it spuriously.
|
||||
/// </summary>
|
||||
internal void RaiseValueChanged() => ValueChanged?.Invoke(this);
|
||||
|
||||
/// <summary>
|
||||
/// True for receive-direction params (decoded from incoming CAN frames).
|
||||
/// False for transmit-direction params (packed into outgoing frames).
|
||||
|
||||
23
Models/CustomCommand.cs
Normal file
23
Models/CustomCommand.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace HC_APTBS.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A named, user-saved KWP custom command. Persisted in
|
||||
/// <c>%UserProfile%\.HC_APTBS\config\custom_commands.xml</c> and managed by the
|
||||
/// Developer Tools page's saved-commands library.
|
||||
///
|
||||
/// <para><see cref="HexBytes"/> stores the raw payload as a space-separated
|
||||
/// hex string (e.g. <c>"19 02 00 44"</c>) — the same format the Developer
|
||||
/// page's hex parser accepts. Round-trip parsing happens at send time, not
|
||||
/// here, so the user can edit the string in place.</para>
|
||||
/// </summary>
|
||||
public sealed partial class CustomCommand : ObservableObject
|
||||
{
|
||||
/// <summary>Display name shown in the saved-commands list.</summary>
|
||||
[ObservableProperty] private string _name = string.Empty;
|
||||
|
||||
/// <summary>Space-separated hex bytes that form the KWP custom payload.</summary>
|
||||
[ObservableProperty] private string _hexBytes = string.Empty;
|
||||
}
|
||||
}
|
||||
26
Models/EepromPassword.cs
Normal file
26
Models/EepromPassword.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace HC_APTBS.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A named EEPROM unlock password. Persisted in
|
||||
/// <c>%UserProfile%\.HC_APTBS\config\eeprom_passwords.xml</c> and managed by
|
||||
/// the Developer Tools page's password library.
|
||||
///
|
||||
/// <para>Applying a password sends the KWP unlock packet
|
||||
/// <c>[0x18 0x00 Zone KeyHi KeyLo]</c> over the persistent K-Line session.
|
||||
/// Keys vary across pump variants, so users typically include the variant
|
||||
/// in <see cref="Name"/> to disambiguate.</para>
|
||||
/// </summary>
|
||||
public sealed partial class EepromPassword : ObservableObject
|
||||
{
|
||||
/// <summary>Display name shown in the password list (e.g. "Bosch v2 — Zone 0").</summary>
|
||||
[ObservableProperty] private string _name = string.Empty;
|
||||
|
||||
/// <summary>EEPROM zone identifier (typically 0–3 plus 8 for the magic zone).</summary>
|
||||
[ObservableProperty] private byte _zone;
|
||||
|
||||
/// <summary>16-bit unlock key. Big-endian on the wire (KeyHi then KeyLo).</summary>
|
||||
[ObservableProperty] private ushort _key;
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,21 @@ namespace HC_APTBS.Models
|
||||
/// <summary>Lock-angle (shaft timing reference) in degrees.</summary>
|
||||
public string Chaveta { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Alternative K-Line pump-IDs that should resolve to this canonical pump.
|
||||
/// Used when the ECU reports a Bosch number (e.g. 1093423001) that differs from
|
||||
/// this pump's canonical <see cref="Id"/> (e.g. 0470504027). Loaded from the
|
||||
/// per-pump <c><Aliases><KlineId></c> entries in <c>pumps.xml</c>.
|
||||
/// </summary>
|
||||
public List<string> KlineAliases { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Alternative <c>ModelReference</c> strings (12-char ECU prefix, e.g. ME190297C150)
|
||||
/// that should resolve to this canonical pump. Loaded from the per-pump
|
||||
/// <c><Aliases><ModelRef></c> entries in <c>pumps.xml</c>.
|
||||
/// </summary>
|
||||
public List<string> ModelRefAliases { get; set; } = new();
|
||||
|
||||
// ── Physical parameters ───────────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace HC_APTBS.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Sequential state of the Tests page wizard flow.
|
||||
/// Advance is gated: Plan → Preconditions (when phases are enabled),
|
||||
/// Preconditions → Running (when all required checks pass),
|
||||
/// Running → Done (when the bench service reports the test finished).
|
||||
/// Back navigation is allowed only between Plan and Preconditions.
|
||||
/// </summary>
|
||||
public enum TestFlowState
|
||||
{
|
||||
/// <summary>Operator selects tests and enables individual phases.</summary>
|
||||
Plan,
|
||||
|
||||
/// <summary>Pre-run safety and readiness checklist; Start is hard-blocked until all green.</summary>
|
||||
Preconditions,
|
||||
|
||||
/// <summary>Test is executing on the bench. Live phase timeline and measurements.</summary>
|
||||
Running,
|
||||
|
||||
/// <summary>Test finished (complete or aborted). Summary and next-step actions.</summary>
|
||||
Done
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user