更新20260526

This commit is contained in:
GukSang.Jin
2026-05-25 18:54:22 +08:00
parent 6965d39560
commit ededa3a80c

View File

@@ -23,7 +23,8 @@ public sealed class CValueCalibrationViewModel : PageViewModel
private const double PressureDifferenceMaximum = 5000;
private const double CValueMinimum = 0;
private const double CValueMaximum = 1000;
private const double BaselineOxygenDisplayScale = 100;
private const double FractionalOxygenMaximum = 0.3;
private const double PlausibleOxygenMinimum = 1;
private const ushort CirculatingWaterCoil = 49;
private const ushort SamplingPumpCoil = 50;
private const ushort IgniterCoil = 53;
@@ -41,6 +42,13 @@ public sealed class CValueCalibrationViewModel : PageViewModel
private const string MethaneValveAction = "甲烷阀";
private const string BaselineCollectionAction = "基线采集";
private const string CalibrationStartAction = "标定开始";
private static readonly ModbusFloatByteOrder[] FloatByteOrders =
[
ModbusFloatByteOrder.Abcd,
ModbusFloatByteOrder.Cdab,
ModbusFloatByteOrder.Badc,
ModbusFloatByteOrder.Dcba
];
private readonly Action _closeAction;
private readonly Action _helpAction;
@@ -185,13 +193,10 @@ public sealed class CValueCalibrationViewModel : PageViewModel
private void RefreshDeviceValues()
{
BaselineOxygenText = ReadRangedFloatText(
BaselineOxygenText = ReadOxygenPercentText(
"BaselineOxygen",
BaselineOxygenRegister,
OxygenMinimum,
OxygenMaximum / BaselineOxygenDisplayScale,
"0.00",
BaselineOxygenDisplayScale);
"0.00");
TemperatureText = ReadRangedFloatText(
"Temperature",
TemperatureRegister,
@@ -224,8 +229,7 @@ public sealed class CValueCalibrationViewModel : PageViewModel
ushort registerAddress,
double minimum,
double maximum,
string format,
double displayScale = 1)
string format)
{
if (!_tcpDeviceConnectionService.TryReadFloatValues(registerAddress, out var result))
{
@@ -239,7 +243,107 @@ public sealed class CValueCalibrationViewModel : PageViewModel
}
LogFloatDiagnostic(label, registerAddress, result, byteOrder, matchCount);
return NormalizeDisplayValue(value * displayScale).ToString(format, CultureInfo.InvariantCulture);
return NormalizeDisplayValue(value).ToString(format, CultureInfo.InvariantCulture);
}
private string ReadOxygenPercentText(
string label,
ushort registerAddress,
string format)
{
if (!_tcpDeviceConnectionService.TryReadFloatValues(registerAddress, out var result))
{
return string.Empty;
}
if (!TrySelectOxygenPercent(result, out var byteOrder, out var value, out var matchCount))
{
LogFloatDiagnostic(label, registerAddress, result, null, matchCount);
return string.Empty;
}
LogFloatDiagnostic(label, registerAddress, result, byteOrder, matchCount);
return NormalizeDisplayValue(value).ToString(format, CultureInfo.InvariantCulture);
}
private static bool TrySelectOxygenPercent(
ModbusFloatReadResult result,
out ModbusFloatByteOrder byteOrder,
out double value,
out int matchCount)
{
var candidates = FloatByteOrders
.Select(candidate => CreateOxygenCandidate(candidate, result.GetValue(candidate)))
.Where(candidate => candidate.IsValid)
.ToArray();
matchCount = candidates.Length;
var selected = candidates.FirstOrDefault(
candidate => candidate.ByteOrder == ModbusFloatByteOrder.Abcd && candidate.IsPlausible);
if (!selected.IsValid)
{
var plausibleCandidates = candidates
.Where(candidate => candidate.IsPlausible)
.ToArray();
if (plausibleCandidates.Length == 1)
{
selected = plausibleCandidates[0];
}
}
if (!selected.IsValid)
{
selected = candidates.FirstOrDefault(candidate => candidate.ByteOrder == ModbusFloatByteOrder.Abcd);
}
if (!selected.IsValid && candidates.Length == 1)
{
selected = candidates[0];
}
if (!selected.IsValid)
{
byteOrder = default;
value = double.NaN;
return false;
}
byteOrder = selected.ByteOrder;
value = selected.PercentValue;
return true;
}
private static OxygenPercentCandidate CreateOxygenCandidate(
ModbusFloatByteOrder byteOrder,
double rawValue)
{
if (!double.IsFinite(rawValue) || rawValue < OxygenMinimum)
{
return default;
}
double percentValue;
if (rawValue > OxygenMinimum && rawValue <= FractionalOxygenMaximum)
{
percentValue = rawValue * 100;
}
else if (rawValue <= OxygenMaximum)
{
percentValue = rawValue;
}
else
{
return default;
}
return new OxygenPercentCandidate(
byteOrder,
percentValue,
percentValue >= PlausibleOxygenMinimum && percentValue <= OxygenMaximum,
true);
}
private void LogFloatDiagnostic(
@@ -523,6 +627,12 @@ public sealed class CValueCalibrationViewModel : PageViewModel
return action is BaselineCollectionAction or CalibrationStartAction;
}
private readonly record struct OxygenPercentCandidate(
ModbusFloatByteOrder ByteOrder,
double PercentValue,
bool IsPlausible,
bool IsValid);
private sealed class PairedActionWaitState(
ushort completionCoilAddress,
string waitingText,