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

@@ -299,7 +299,9 @@ namespace HC_APTBS.Infrastructure.Kwp
{
var packet = ReceivePacket();
packets.Add(packet); // TODO: Maybe don't add the packet if it's an Ack
if (packet is AckPacket || packet is NakPacket)
//SendAckPacket();
if (packet is AckPacket || packet is NakPacket)
{
break;
}

View File

@@ -398,9 +398,10 @@ namespace HC_APTBS.Infrastructure.Pcan
double previousValue = param.Value;
if (param.Name == BenchParameterNames.Temp || param.Name == PumpParameterNames.Temp)
if (param.Name == PumpParameterNames.Temp)
{
// Temperature uses a special packed BCD / signed format depending on sensor type.
// Only pump "Temp" uses BCD / signed format. Bench temperatures
// ("BenchTemp", "T-in", etc.) go through the generic path below.
param.Value = DecodeTempValue(data, param);
}
else if (param.Name == PumpParameterNames.Rpm)
@@ -413,23 +414,34 @@ namespace HC_APTBS.Infrastructure.Pcan
{
// Generic 1-byte, 2-byte, or 3-byte big-endian integer.
int byteSpan = Math.Abs(param.ByteH - param.ByteL);
double rawValue;
if (byteSpan == 0)
{
param.Value = data[param.ByteL];
rawValue = data[param.ByteL];
}
else if (byteSpan == 1)
{
param.Value = (data[param.ByteH] << 8) | data[param.ByteL];
rawValue = (data[param.ByteH] << 8) | data[param.ByteL];
}
else
{
// 3-byte little-endian variant used for encoder/pulse counters.
param.Value = (data[param.ByteL + 2] << 16)
| (data[param.ByteL + 1] << 8)
| data[param.ByteL];
rawValue = (data[param.ByteL + 2] << 16)
| (data[param.ByteL + 1] << 8)
| data[param.ByteL];
}
param.Value = param.GetTransformResult();
if (param.UseLegacyTransform)
{
// Pump params: store raw then apply P1-P6 rational transfer function.
param.Value = rawValue;
param.Value = param.GetTransformResult();
}
else
{
// Bench params: apply factor/offset calibration directly.
param.Value = param.Calibrate(rawValue);
}
if (double.IsInfinity(param.Value)) param.Value = 0;
}