更新
This commit is contained in:
@@ -13,12 +13,17 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
|
||||
private const ushort AbsorbanceRegister = 120;
|
||||
private const double AbsorbanceMinimum = 0;
|
||||
private const double AbsorbanceMaximum = 100;
|
||||
private const double AbsorbanceStableTolerance = 0.25;
|
||||
private const int AbsorbanceStableReadCount = 2;
|
||||
|
||||
private readonly Action _closeAction;
|
||||
private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService;
|
||||
private readonly DispatcherTimer _refreshTimer;
|
||||
private readonly HashSet<ushort> _loggedFloatDiagnostics = [];
|
||||
private readonly HashSet<ushort> _loggedInvalidFloatDiagnostics = [];
|
||||
private double? _stableAbsorbance;
|
||||
private double? _pendingAbsorbance;
|
||||
private int _pendingAbsorbanceReadCount;
|
||||
private string _absorbanceText = "";
|
||||
private string _lastCalibration = "待校准";
|
||||
|
||||
@@ -90,34 +95,85 @@ public sealed class SmokeDensitySettingsViewModel : PageViewModel
|
||||
|
||||
private void RefreshDeviceValues()
|
||||
{
|
||||
AbsorbanceText = ReadRangedFloatText(
|
||||
if (!TryReadRangedFloatValue(
|
||||
"Absorbance",
|
||||
AbsorbanceRegister,
|
||||
AbsorbanceMinimum,
|
||||
AbsorbanceMaximum,
|
||||
"0.00");
|
||||
out var value))
|
||||
{
|
||||
if (!_stableAbsorbance.HasValue)
|
||||
{
|
||||
AbsorbanceText = string.Empty;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (TryUpdateStableAbsorbance(value, out var stableValue))
|
||||
{
|
||||
AbsorbanceText = stableValue.ToString("0.00", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadRangedFloatText(
|
||||
private bool TryReadRangedFloatValue(
|
||||
string label,
|
||||
ushort registerAddress,
|
||||
double minimum,
|
||||
double maximum,
|
||||
string format)
|
||||
out double value)
|
||||
{
|
||||
value = double.NaN;
|
||||
|
||||
if (!_tcpDeviceConnectionService.TryReadFloatValues(registerAddress, out var result))
|
||||
{
|
||||
return string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ModbusFloatSelector.TrySelectRangedFloat(result, minimum, maximum, out var byteOrder, out var value, out var matchCount))
|
||||
if (!ModbusFloatSelector.TrySelectRangedFloat(result, minimum, maximum, out var byteOrder, out var selectedValue, out var matchCount))
|
||||
{
|
||||
LogFloatDiagnostic(label, registerAddress, result, null, matchCount);
|
||||
return string.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
LogFloatDiagnostic(label, registerAddress, result, byteOrder, matchCount);
|
||||
return NormalizeDisplayValue(value).ToString(format, CultureInfo.InvariantCulture);
|
||||
value = NormalizeDisplayValue(selectedValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryUpdateStableAbsorbance(double value, out double stableValue)
|
||||
{
|
||||
stableValue = _stableAbsorbance ?? value;
|
||||
|
||||
if (_stableAbsorbance.HasValue
|
||||
&& Math.Abs(value - _stableAbsorbance.Value) <= AbsorbanceStableTolerance)
|
||||
{
|
||||
_pendingAbsorbance = null;
|
||||
_pendingAbsorbanceReadCount = 0;
|
||||
stableValue = _stableAbsorbance.Value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_pendingAbsorbance.HasValue
|
||||
|| Math.Abs(value - _pendingAbsorbance.Value) > AbsorbanceStableTolerance)
|
||||
{
|
||||
_pendingAbsorbance = value;
|
||||
_pendingAbsorbanceReadCount = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
_pendingAbsorbanceReadCount++;
|
||||
|
||||
if (_pendingAbsorbanceReadCount < AbsorbanceStableReadCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_stableAbsorbance = value;
|
||||
_pendingAbsorbance = null;
|
||||
_pendingAbsorbanceReadCount = 0;
|
||||
stableValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void LogFloatDiagnostic(
|
||||
|
||||
Reference in New Issue
Block a user