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>
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.StatusChangedfires every 1000ms with"Unlocking... {pct}% ({MM:SS})"UnlockService.UnlockCompletedfires once withtrue/falseMainViewModelsubscribes and pipes status intoVerboseStatus(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
Ellipsering (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)
LBLStateat top: live lock/immo status from CAN feedback ("Bloqueada/Desbloqueada")LBLVerboseat bottom: phase description ("Unlocking...", "Testing...", "Sending")- "Cerrar" (Close) button disabled until progress reaches 100%
- Window close prevented via
OnWindowClosinguntil 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()— callsCancellationTokenSource.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.