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>
12 KiB
HC_APTBS
What this is
WPF desktop application (.NET 10 / x64) that controls a VP44 diesel injection pump test bench.
- Reads/writes bench sensors (temperature, RPM, flow) via CAN bus (PCAN-Basic, 500 kbps)
- Communicates with the pump ECU via K-Line/KWP2000 (FTDI USB adapter, 9600 bps)
- Runs automated multi-phase test sequences with PID temperature control
- Generates PDF test reports (QuestPDF)
- Supports Ford VP44 immobilizer unlock via CAN (Types 1 & 2)
Build
Windows only, .NET 10 x64. dotnet build -r win-x64 from solution root. SDK pinned in global.json. No WSL/Linux — native DLLs (PCANBasic.dll, ftd2xx.dll) are x64 Windows binaries. No test project; validation is code review + manual hardware testing.
Stack
- C# / .NET 10, WPF, XAML
- CommunityToolkit.Mvvm:
[ObservableProperty],[RelayCommand] - Microsoft.Extensions.DependencyInjection / Hosting for bootstrap
- QuestPDF 2025.3.2 (requires
LicenseType.Communityin constructor) - LiveChartsCore.SkiaSharpView.WPF 2.0.0-rc3.5 for real-time charts
- Extended.Wpf.Toolkit 4.6.1 (AvalonDock, NumericUpDown, BusyIndicator)
- Native DLLs in output:
PCANBasic.dll,ftd2xx.dll(x64 only)
Architecture
Infrastructure/
Pcan/PcanBasic.cs — Vendor P/Invoke file. NEVER modify.
Pcan/PcanAdapter.cs — CAN read thread, OEM legitimation, frame decode, IIR filter, liveness tracking
Kwp/FtdiInterface.cs — FTDI D2XX wrapper (manual LoadLibrary, not NativeLibrary.Load)
Kwp/KwpCommon.cs — 5-baud slow-init, complement-ACK byte I/O
Kwp/KW1281Connection.cs — KWP/KW1281 protocol state machine
Kwp/Packets/ — 10 packet types (Ack, Nak, FaultCodes, Eeprom R/W, Custom, etc.)
Logging/AppLogger.cs — Daily rotating log files (ERR/WAR/MSG/DBG)
Services/
ICanService.cs — CAN bus abstraction (parameter map, frame routing, liveness)
IBenchService.cs — Test orchestration, RPM/temp control, relay control
IKwpService.cs — K-Line ECU diagnostics (keep-alive, EEPROM, DTCs, DFI)
IUnlockService.cs — Ford VP44 immobilizer unlock state machine
IConfigurationService.cs — XML persistence for all config files
ICalibrationService.cs — Sensor calibration operations
IPdfService.cs — PDF test report generation
Services/Impl/
BenchService.cs — Test orchestration, temperature PID, relay control (background Task)
BenchPidController.cs — Discrete-time PID for RPM ramp (derivative-on-measurement, anti-windup)
KwpService.cs — All KWP operations; persistent session with keep-alive loop
UnlockService.cs — Ford unlock: 600.5s Phase 1 + TestUnlock Phase 2 + verification
ConfigurationService.cs — XML persistence for pumps, bench, config, clients, sensors, alarms, status
CalibrationService.cs — Sensor calibration
PdfService.cs — QuestPDF report generation (multi-page, charts, verdict)
ReportChartRenderer.cs — SVG chart rendering for PDF tolerance-band visualizations
ReportTheme.cs — Report styling constants
Models/
CanBusParameter.cs — CAN parameter model + BenchParameterNames/PumpParameterNames/KlineKeys constants
BenchConfiguration.cs — Bench config + embedded AppSettings (PID, timers, safety limits)
PumpDefinition.cs — Pump model, CAN params, tests, K-Line data
TestDefinition.cs — Test type + phase list + tolerance evaluation
PhaseDefinition.cs — Phase readies/sends/receives/results
TestParameter.cs — Measurement point (name, value, tolerance)
TestResult.cs — Accumulated result with samples and pass/fail evaluation
MeasurementSample.cs — Single timestamped measurement
SensorConfiguration.cs — ADC calibration (voltage → engineering units)
Relay.cs — Relay output + RotationDirection/EncoderMode/BaudrateSelection constants
Alarm.cs — Alarm condition (bit, description, criticality, active state)
PumpStatusDefinition.cs — Status word bit definitions with color-coded states
RpmVoltageRelation.cs — RPM → voltage lookup table entry
KLineConnectionState.cs — K-Line session state enum
Converters/
BoolToPassFailBrushConverter.cs
HexColorToBrushConverter.cs
ViewModels/ — [ObservableProperty] / [RelayCommand], no UI logic
MainViewModel.cs — Central orchestrator, event marshalling, child VMs
PumpIdentificationViewModel.cs — Pump selection + K-Line ECU read
DfiManageViewModel.cs — DFI calibration read/write/auto-adjust
TestPanelViewModel.cs — Test suite management (phase enable/disable)
TestDisplayViewModel.cs — Current test execution progress
ResultDisplayViewModel.cs — Test result table (per-phase pass/fail)
PumpControlViewModel.cs — Manual pump control sliders (ME, FBKW, PreIn)
BenchControlViewModel.cs — Bench control (rotation, RPM ramp, oil pump)
FlowmeterChartViewModel.cs — Real-time flowmeter charts
AngleDisplayViewModel.cs — Encoder angle monitoring (PSG, INJ, Manual, Lock Angle)
StatusDisplayViewModel.cs — Pump status word display
Dialogs/ — KlineErrors, Progress, Report, UserCheck ViewModels
Views/
MainWindow.xaml — Root UI (multi-panel layout)
Dialogs/ — KlineErrorsDialog, ProgressDialog, ReportDialog, UserCheckDialog
UserControls/ — AngleDisplay, BenchParamConfig, DfiManage, FlowmeterChart,
PumpControl, PumpIdentification, ResultDisplay, StatusDisplay,
TestDisplay, TestPanel
Configuration files
All XML files stored in %UserProfile%\.HC_APTBS\config\:
| File | Purpose |
|---|---|
config.xml |
Global settings: temp limits, PID tuning, refresh rates, safety limits, encoder, motor, company info, K-Line port, language, users, RPM-voltage relations |
pumps.xml |
Pump database: per-pump identity, CAN parameters (P1–P6 legacy), test definitions with phases |
bench.xml |
Bench CAN parameters (Factor/Offset model) + relay definitions. Embedded default fallback in code |
sensors.xml |
ADC sensor calibrations (channel → voltage → engineering units) |
clients.xml |
Client/operator directory (name → contact) |
alarms.xml |
Alarm definitions (bit position, description, criticality) |
status.xml |
Pump status word bit definitions with color-coded states |
Constants quick reference
Defined in Models/CanBusParameter.cs:
BenchParameterNames— RPM, Counter, BaudRate, BenchTemp, T-in, T-out, T4, QDelivery, QOver, Alarms, Pressure, AnalogSensor2, encoders (PSG/INJ/Manual)PumpParameterNames— me, FBKW, mepi, RPM, Temp, Tein, MemoryRequest, TestUnlock, TestImmo, Status, Empf3KlineKeys— pumpID, SerialNumber, ModelReference, DFI, ErrorCodes, SWV1, SWV2, PumpControl, DataRecord, resultRelayNames— Electronic, OilPump, DepositCooler, DepositHeater, Counter, Direction, TinCooler, Pulse4Signal, Flasher (inModels/Relay.cs)
Rules for all edits
Always:
- Read the file before editing it
- Keep XML doc comments on all public types and members
- Use
BenchParameterNames/PumpParameterNames/KlineKeys/RelayNamesconstants — no magic strings - Marshal to the UI thread when consuming
IBenchServiceorIKwpServiceevents (they fire on background threads) - Use
CultureInfo.InvariantCulturewhen parsing/formatting doubles in XML (avoid locale bugs) - Log skipped or malformed XML elements — never silently swallow parse failures
- New bench parameters must use Factor/Offset calibration, not P1–P6 (legacy model is for pump params only)
Never:
- Modify
Infrastructure/Pcan/PcanBasic.cs(vendor file, intentionally untouched) - Modify anything under
old_source/(archived reference only) - Add logic to View code-behind files
- Add
Thread.Sleep, allocations, or logging inside the per-byte K-Line loops inKwpCommon/KW1281Connection
Protocol constants
Do not change without knowing why. Use /protocol-ref skill for full reference including DFI encoding, IIR filter, OEM legitimation, and K-Line timing.
Conventions
- ViewModels in
/ViewModels, Views in/Views, Models in/Models - Async methods use
Asyncsuffix - Commit format:
feat:,fix:,refactor:(conventional commits) - Git remote: self-hosted Gitea at 192.168.8.130
Known gaps (from old_source comparison)
See docs/ guidelines for full specs. Priority: CRITICAL > HIGH > MEDIUM > LOW.
CRITICAL:
- No config XML validation — malformed files silently produce partial/default state
HIGH — Missing safety features:
- No QOver zero-flow safety check (old: emergency stop if QOver==0 while RPM>300 + oil pump on)
- No safety dialogs: 27V warning, oil pump confirmation, RPM warning
- Alarm bit collection during tests not wired up (
PhaseDefinition.RecordErrorBitnever called) - No per-sample real-time UI callback during measurement (old fired per-sample events for live charts)
- Pump parameters (ME/FBKW/PreIn) not zeroed between test phases
HIGH — Missing features:
- Ford unlock progress UI (service exists, no View — old had WUnlocker.xaml with visual ring + progress bar)
- No localization system (old had Spanish/English resource dictionaries with runtime switching)
- No encryption (old encrypted user passwords with AES-256 + pump data with Rijndael; new stores plaintext)
- No KlineIDs auto-mapping (old remembered K-Line ID → pump ID associations)
MEDIUM — Missing UI components:
- WConfigPanel (full settings dialog)
- WUsersManage (user CRUD — only auth dialog exists)
- KlineIDSelection (COM port selection for K-Line)
- BitDisplay / SingleBit (bit-level status toggles)
- TimerDisplay (test timer/countdown)
- FilteredComboBox (searchable dropdown)
- PDF report observations/notes section missing from interface
LOW:
- 4ms PeriodicTimer may fire at ~15ms on Windows (old MultimediaTimer had ~1ms precision)
- Sensor calibration divide-by-zero when MaxVolt==MinVolt (no guard)
- P1–P6 transfer function can produce Infinity/NaN (no denominator check)
- CAN parameter byteh/bytel not bounds-checked to 0–7
Known debt
Do not worsen before addressing deliberately. See memory file project_known_debt.md for details.
Additional debt items:
KW1281ConnectionallocatesList<byte>per packet — GC pressure under long K-Line sessionsPcanAdapter.DrainMessageQueuepolls withThread.Sleep(2)— hardcoded, was configurable in old- No unit tests exist yet
- Users stored as plaintext
user:passwordin config.xml - Config file format has no version tracking or migration logic
- Pump ID uniqueness not enforced on load
ParseEcuText()depends on exact spacing format (fragile)- AppSettings properties have no bounds validation (timer intervals, safety limits)
SaveSettings()triggersSaveSensors()+SaveClients()as side effects
CFG/pump data migration
The old system had 32 CFG files defining pump-specific data NOT present in the new XML model:
- Status bit reaction codes (0=none, 1=abort, 2=warning, 3=log) — controlled test flow on errors
- BIP-STATUS definitions (needle-motion detection) — absent from new system entirely
- Diagnostic RAM addresses (solenoid timing, temperature compensation, learning procedures)
- Flow regulator sensitivity parameters (measurement time adjustment, tolerance, FM sensitivity)
- EEPROM/EPROM/RAM passwords per pump family
- CAN-BUS-KENNUNG protocol variant code (0/1/2/6/10) — derived implicitly in new code
See
docs/gap-pump-data-migration.mdfor migration field mapping.