Commit Graph

4 Commits

Author SHA1 Message Date
da0581967b fix: gate Ford VP44 unlock on CAN liveness to prevent false-unlocked reads
Before this fix, StartUnlockIfRequired was called immediately after
registering the pump's CAN parameters, before any frames had been
decoded. The TestUnlock parameter's zero-initialised Value was
interpreted as "unlocked" for Type 1 pumps, causing Phase 1 to be
skipped and UnlockCompleted(true) to fire falsely.

Changes:
- ICanService: add IsPumpAlive property (volatile-backed in PcanAdapter)
- PcanAdapter: implement IsPumpAlive; mark _pumpAlive/_benchAlive volatile
  for safe cross-thread reads
- MainViewModel: replace direct StartUnlockIfRequired call with a
  fire-and-forget WaitForPumpCanThenUnlockAsync that waits for
  PumpLivenessChanged(true) + 250 ms grace, then invokes unlock on the
  UI thread; cancellation on pump change or CAN disconnect via
  _pumpLivenessCts
- UnlockService.UnlockAsync: skip Phase 2 state-machine when observer
  seed already reports unlocked (senders still run to prevent re-lock)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 16:52:16 +02:00
9a593e4ff2 fix: stop UI freeze when selecting a pump that needs immobilizer unlock
Phase 2 TestUnlock handshake was synchronous (Thread.Sleep x 8 = 4 s) and
the continuation after Phase 1 marshalled back to the WPF dispatcher via
the captured SynchronizationContext, so the eight 500 ms sleeps froze the
UI right before unlock completed.

- UnlockService.RunTestUnlockSequence -> async RunTestUnlockSequenceAsync
  with Task.Delay(500, ct) and ConfigureAwait(false)
- Add ConfigureAwait(false) on every internal await in UnlockService so
  continuations no longer hop to the UI thread (Task.WhenAll, Task.Delay,
  connectedTcs, TryFastUnlockAsync, fast-unlock settle delay)
- CancellationToken now propagates through Phase 2, so the snackbar Cancel
  button can interrupt the handshake within 500 ms instead of waiting out
  all eight Thread.Sleeps

Includes the companion observer in IUnlockService / UnlockService
(PumpUnlocked event, IsPumpUnlocked, StartObserver/StopObserver) that
the Phase 1 wait now races against — lets any source of unlock (fast
unlock, external manual, CAN flood finally working) short-circuit the
600 s timer as soon as the CAN TestUnlock parameter confirms it.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 14:36:45 +02:00
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
6e1b929e2f initial commit 2026-04-11 12:45:18 +02:00