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>
75 lines
3.8 KiB
Markdown
75 lines
3.8 KiB
Markdown
# 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.
|