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