This commit is contained in:
GukSang.Jin
2026-05-22 15:15:48 +08:00
parent ff49f9f8e2
commit e2ee1b2a2d

View File

@@ -11,10 +11,14 @@ namespace ConeCalorimeter.ViewModels;
public sealed class SmokeDensitySettingsViewModel : PageViewModel
{
private const ushort AbsorbanceRegister = 120;
private const double AbsorbanceMinimum = 0;
private const double AbsorbanceMaximum = 100;
private readonly Action _closeAction;
private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService;
private readonly DispatcherTimer _refreshTimer;
private readonly HashSet<ushort> _loggedFloatDiagnostics = [];
private readonly HashSet<ushort> _loggedInvalidFloatDiagnostics = [];
private string _absorbanceText = "";
private string _lastCalibration = "待校准";
@@ -86,9 +90,67 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
private void RefreshDeviceValues()
{
AbsorbanceText = _tcpDeviceConnectionService.TryReadFloat(AbsorbanceRegister, out var value)
? value.ToString("0.00", CultureInfo.InvariantCulture)
: string.Empty;
AbsorbanceText = ReadRangedFloatText(
"Absorbance",
AbsorbanceRegister,
AbsorbanceMinimum,
AbsorbanceMaximum,
"0.00");
}
private string ReadRangedFloatText(
string label,
ushort registerAddress,
double minimum,
double maximum,
string format)
{
if (!_tcpDeviceConnectionService.TryReadFloatValues(registerAddress, out var result))
{
return string.Empty;
}
if (!ModbusFloatSelector.TrySelectRangedFloat(result, minimum, maximum, 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 void LogFloatDiagnostic(
string label,
ushort registerAddress,
ModbusFloatReadResult result,
ModbusFloatByteOrder? selectedByteOrder,
int matchCount)
{
if (selectedByteOrder is null)
{
if (!_loggedInvalidFloatDiagnostics.Add(registerAddress))
{
return;
}
}
else if (!_loggedFloatDiagnostics.Add(registerAddress))
{
return;
}
var selectedText = selectedByteOrder?.ToString() ?? "none";
Debug.WriteLine(
$"Smoke density float {label} register {registerAddress} raw [{result.RawHex}], "
+ $"ABCD={result.Abcd:G9}, CDAB={result.Cdab:G9}, "
+ $"BADC={result.Badc:G9}, DCBA={result.Dcba:G9}, "
+ $"selected={selectedText}, matches={matchCount}.");
}
private static double NormalizeDisplayValue(double value)
{
return Math.Abs(value) < 0.005 ? 0 : value;
}
private static bool TryGetCalibrationCoil(string label, out ushort coilAddress)