Files
HC_APTBS/docs/gap-ford-unlock-ui.md
LucianoDev c617854c09 feat: implement SavePump/SaveAlarms, fix config round-trip bugs, redesign PDF reports
Config system fixes:
- Implement SavePump() — full XML serialization with insert/update by pump ID
- Add CanBusParameter.ToPumpXml() for legacy P1-P6 pump param format
- Fix LastRotationDirection never loaded in LoadSettings()
- Add SaveAlarms() to ConfigurationService and IConfigurationService
- Remove dead fields AppSettings.Clients and AppSettings.PumpIds

PDF report redesign:
- Professional layout with charts, verdict badges, and tolerance bands
- Add ReportChartRenderer (SVG) and ReportTheme styling constants
- Embed default_logo.png as fallback report logo

Documentation:
- Add gap analysis docs (config validation, ford unlock, missing features)
- Update CLAUDE.md architecture, known gaps, and debt tracking

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

3.8 KiB

Gap: Ford Unlock Progress UI

Problem

The UnlockService backend is fully functional (Phase 1 + Phase 2 + verification), but there is no dedicated UI for displaying unlock progress. The old app had WUnlocker.xaml — a modal dialog with a visual progress ring and status text.

Current State

  • UnlockService.StatusChanged fires every 1000ms with "Unlocking... {pct}% ({MM:SS})"
  • UnlockService.UnlockCompleted fires once with true/false
  • MainViewModel subscribes and pipes status into VerboseStatus (displayed as plain text somewhere in MainWindow)
  • No progress bar, no percentage display, no cancel button, no dedicated dialog

Old UI Reference (WUnlocker.xaml)

  • Standalone modal Window (300x400px), dark background (#FF2B2929), Topmost, centered on owner
  • Decorative Ellipse ring (200x200, #4D4D4D stroke, 10px thick) as the focal point
  • Inside the ring: large percentage (Courier New 60pt), "P R O G R E S S" label, elapsed time (MM:SS)
  • LBLState at top: live lock/immo status from CAN feedback ("Bloqueada/Desbloqueada")
  • LBLVerbose at bottom: phase description ("Unlocking...", "Testing...", "Sending")
  • "Cerrar" (Close) button disabled until progress reaches 100%
  • Window close prevented via OnWindowClosing until completion

Spec for New Implementation

UnlockDialog.xaml (View)

  • Modal dialog (MVVM, no code-behind logic)
  • Progress bar (0-100%) + percentage text
  • Elapsed time display (MM:SS)
  • Phase indicator: "Phase 1: Sending unlock signals" / "Phase 2: Testing" / "Verifying..."
  • Current unlock type indicator (Type 1 / Type 2)
  • Cancel button (disabled during Phase 2 — it cannot be cancelled once started)
  • Close button (enabled only after completion)
  • Result indicator: green checkmark (success) / red X (failed)

UnlockViewModel.cs (ViewModel)

  • [ObservableProperty] double Progress
  • [ObservableProperty] string ElapsedTime
  • [ObservableProperty] string Phase
  • [ObservableProperty] string Result
  • [ObservableProperty] bool IsComplete
  • [ObservableProperty] bool CanCancel
  • [RelayCommand] Cancel() — calls CancellationTokenSource.Cancel()
  • Subscribe to IUnlockService.StatusChanged — parse percentage from status string
  • Subscribe to IUnlockService.UnlockCompleted — set result and enable close

Integration

  • Trigger: button in MainViewModel (currently exists but needs to open the dialog)
  • The dialog should be shown via a dialog service or Window.ShowDialog() from MainViewModel
  • Marshal all event handlers to UI thread

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

Duration

Phase 1: 600,500 ms (10 min 0.5 sec). Phase 2: ~4 sec (8 messages x 500ms). Total: ~604.5 sec.

Known Issue in Unlock Verification

The Type 1 verification logic may be inverted compared to the old code. Old: Lock = (valor != 0) meant non-zero = LOCKED. New: Value != 0 returned as SUCCESS (unlocked). Needs hardware testing to confirm which is correct.

Missing Feature: TestImmo Check

Old code tracked both TestUnlock and TestImmo CAN parameters and displayed combined status. New code only checks TestUnlock, ignoring TestImmo entirely. Consider adding the immobilizer state check for completeness.