feat: redesign bench calibration (factor/offset), add Ttank/P2 displays, fix sensor calibration

- Replace P1-P6 rational transfer function with factor/offset model for bench params
- Add explicit rx/tx direction flags in bench XML configuration
- Add T.Tank (BenchTemp) and P2 (AnalogSensor2) to temperature/pressure display
- Apply SensorConfiguration calibration to pressure channels, fix empty sensors.xml fallback
- Add live value labels to flowmeter charts
- Hide pump live values and PSG encoder standalone label
- Add K-Line connection state model, improve KWP service and status displays
- Restructure .claude/skills into subdirectory format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 21:25:30 +02:00
parent 4964806de1
commit 4891eb6812
20 changed files with 881 additions and 185 deletions

View File

@@ -47,6 +47,18 @@ namespace HC_APTBS.ViewModels
ProgressPercent = pct;
ProgressMessage = msg;
});
// Start loading the pump as soon as the identifier is read from ROM,
// before the full K-Line read completes.
_kwp.PumpIdentified += (pumpId) => App.Current.Dispatcher.Invoke(() =>
{
KlinePumpId = pumpId;
AutoSelectPumpByKlineId(pumpId);
});
// Track K-Line session state for Disconnect button enable/disable.
_kwp.KLineStateChanged += state =>
App.Current.Dispatcher.Invoke(() => KLineState = state);
}
// ── Pump selection ────────────────────────────────────────────────────────
@@ -106,8 +118,14 @@ namespace HC_APTBS.ViewModels
/// <summary>True while a K-Line read is in progress.</summary>
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(ReadKlineCommand))]
[NotifyCanExecuteChangedFor(nameof(DisconnectKLineCommand))]
private bool _isReading;
/// <summary>Current K-Line session state for Disconnect button enable/disable.</summary>
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(DisconnectKLineCommand))]
private KLineConnectionState _kLineState = KLineConnectionState.Disconnected;
/// <summary>DFI calibration angle read from ECU EEPROM.</summary>
[ObservableProperty] private string _klineDfi = "-";
@@ -182,7 +200,10 @@ namespace HC_APTBS.ViewModels
{
KlineDfi = dfi ?? "-";
KlineErrors = errors ?? string.Empty;
KlinePumpId = pumpId ?? string.Empty;
// Preserve the value set by the PumpIdentified event if the
// dictionary entry is empty (e.g. read failed after ident).
if (!string.IsNullOrEmpty(pumpId))
KlinePumpId = pumpId;
KlineSerialNumber = serial ?? string.Empty;
KlineModelRef = modelRef ?? string.Empty;
KlineModelIndex = modelIndex ?? string.Empty;
@@ -193,12 +214,8 @@ namespace HC_APTBS.ViewModels
KlineConnectError = connectErr ?? string.Empty;
});
// Auto-select pump from K-Line pump ID — matches old source behaviour
// where OnPumpConnectClick would call LoadPump(pumpId) after reading.
if (result == "1" && !string.IsNullOrEmpty(pumpId))
{
AutoSelectPumpByKlineId(pumpId);
}
// Pump auto-selection now happens via the PumpIdentified event
// mid-read, so there is no need to call AutoSelectPumpByKlineId here.
// Attach K-Line info to the (now possibly auto-selected) pump.
if (CurrentPump != null)
@@ -212,6 +229,22 @@ namespace HC_APTBS.ViewModels
private bool CanReadKline() => !IsReading;
/// <summary>Closes the persistent K-Line session.</summary>
[RelayCommand(CanExecute = nameof(CanDisconnectKLine))]
private void DisconnectKLine()
{
try
{
_kwp.Disconnect();
}
catch (Exception ex)
{
_log.Error(LogId, $"DisconnectKLine: {ex.Message}");
}
}
private bool CanDisconnectKLine() => !IsReading && KLineState == KLineConnectionState.Connected;
// ── Helpers ───────────────────────────────────────────────────────────────
/// <summary>