Files
HC_APTBS/docs/gap-ford-unlock-ui.md
LucianoDev 37d099cdbd feat: add Ford VP44 unlock progress dialog, K-Line fast unlock, localization, safety dialogs, and settings
Unlock progress UI:
- UnlockProgressDialog with dark-themed progress ring, phase indicator, elapsed
  time, and cancel/close buttons (non-modal, draggable borderless window)
- UnlockProgressViewModel with event-driven progress tracking via IUnlockService
- Triggers on pump selection (manual or K-Line auto-detect), not test start

UnlockService rewrite:
- Persistent CAN senders that outlive the unlock sequence (StopSenders on pump change)
- Concurrent K-Line fast unlock: awaits session Connected, sends RAM timer shortcut
  ({02 88 02 03 A8 01 00}), verifies via CAN TestUnlock before skipping wait
- Fix Type 1 verification (Value == 0 means unlocked, was inverted)

K-Line fast unlock support:
- IKwpService.TryFastUnlockAsync / KwpService implementation

Additional features:
- ILocalizationService with ES/EN resource dictionaries and runtime switching
- Safety dialogs: VoltageWarning, OilPumpConfirm, RpmSafetyWarning
- SettingsDialog for app configuration
- BenchService enhancements, ConfigurationService improvements, PDF report updates
- All UI strings localized via DynamicResource

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 13:22:48 +02:00

4.6 KiB

Gap: Ford Unlock Progress UI — RESOLVED

Status: Implemented

The unlock progress dialog, service refactoring, and K-Line fast unlock are fully implemented.

What was done

1. UnlockProgressDialog (View + ViewModel)

  • Views/Dialogs/UnlockProgressDialog.xaml — Dark-themed non-modal window (#2B2929), borderless with drag support, 200x200 ellipse progress ring, Courier New 60pt percentage, MM:SS elapsed time, phase indicator, linear progress bar, result text (green/red), Cancel + Close buttons
  • Views/Dialogs/UnlockProgressDialog.xaml.csForceClose() for programmatic close, OnWindowClosing prevents user close until IsComplete, OnMouseDrag for window dragging
  • ViewModels/Dialogs/UnlockProgressViewModel.csObservableObject + IDisposable, parses StatusChanged events via regex, marshals to UI thread, CancelCommand (Phase 1 only) / CloseCommand (after completion), [NotifyCanExecuteChangedFor] wiring

2. UnlockService rewrite (Services/Impl/UnlockService.cs)

  • Persistent CAN senders — Start before unlock, run indefinitely until StopSenders() is called on pump deselection. Prevents pump from re-locking after unlock.
  • Concurrent fast unlock — While the 600s CAN wait runs with progress reporting, a parallel task awaits K-Line session Connected state, then:
    1. Checks if pump is already unlocked (via VerifyUnlock)
    2. Sends K-Line fast unlock command ({0x02, 0x88, 0x02, 0x03, 0xA8, 0x01, 0x00}) which writes to pump RAM to fast-forward the internal 10 min timer
    3. Waits 2s, then re-checks VerifyUnlock
    4. If verified → cancels remaining wait, proceeds to Phase 2 immediately
  • IUnlockService.StopSenders() — New interface method, called from MainViewModel.CloseUnlockDialog() on pump change

3. K-Line fast unlock support

  • IKwpService.TryFastUnlockAsync() — New interface method
  • KwpService.TryFastUnlockAsync() — Sends custom command over active session, returns true if no NAK (command accepted, not unlock confirmation)

4. MainViewModel integration

  • Trigger on pump selectionOnPumpChanged() calls StartUnlockIfRequired() for pumps with UnlockType != 0 (both manual and K-Line auto-detect)
  • Non-modal window.Show() instead of .ShowDialog(), user can interact with main UI during 10 min unlock
  • Test start guardsStartTestAsync blocks if unlock is in progress or failed
  • Cleanup on pump changeCloseUnlockDialog() stops senders, cancels CTS, disposes ViewModel, force-closes window

5. Bug fix: Type 1 verification

Fixed. Old code: Lock = valor != 0 (non-zero = LOCKED). New code had return Value != 0 (non-zero = SUCCESS). Changed to return Value == 0. Type 2 (== 0xE4) was already correct.

Protocol Reference

Type 1 (CAN IDs 0x700 + 0x300)

Phase ID Data Interval
Msg1 0x700 B2 00 00 00 00 00 00 00 500 ms
Msg2 0x300 01 48 50 C3 00 00 00 00 50 ms
TestUnlock states 0x700 B2, B6, 23, 24 (byte[0]) x2 500 ms each
Verify TestUnlock param Success when value == 0 One-shot

Type 2 (CAN IDs 0x700 + 0x500)

Phase ID Data Interval
Msg1 0x700 00 00 00 B2 00 00 00 00 500 ms
Msg2 0x500 00 00 00 00 78 00 00 00 50 ms
TestUnlock states 0x700 B2, 24, 24, 24 (byte[3]) x2 500 ms each
Verify TestUnlock param Success when value == 0xE4 One-shot

K-Line fast unlock (timer shortcut)

Command 02 88 02 03 A8 01 00
Effect Writes pump RAM to fast-forward the internal 10 min timer
Prerequisite Active K-Line session + CAN flood senders already running
ACK meaning Command accepted (NOT unlock confirmed — must still verify via CAN TestUnlock)

Duration

  • Phase 1 (normal): 600,500 ms (10 min 0.5 sec)
  • Phase 1 (fast unlock): ~2 sec after K-Line ACK (+ K-Line read time)
  • Phase 2: ~4 sec (8 messages x 500 ms)
  • CAN senders: persist until pump deselection

Critical: CAN sender lifecycle

CAN flood messages must be active before the fast unlock attempt (otherwise the timer resets instantly) and must continue running after unlock completes. Stopping them causes the pump to re-lock. StopSenders() is only called when the pump is deselected.

Remaining gap: TestImmo check

Old code tracked both TestUnlock and TestImmo CAN parameters and displayed combined status ("Inmovilizada/Liberada | Bloqueada/Desbloqueada"). New code only checks TestUnlock. Consider adding immobilizer state display for completeness.