更新一版20260525
This commit is contained in:
@@ -23,6 +23,7 @@ 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 ushort CirculatingWaterCoil = 49;
|
||||
private const ushort SamplingPumpCoil = 50;
|
||||
private const ushort IgniterCoil = 53;
|
||||
@@ -32,6 +33,7 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
private const ushort BaselineEndCoil = 62;
|
||||
private const ushort CalibrationStartCoil = 70;
|
||||
private const ushort CalibrationEndCoil = 72;
|
||||
private static readonly TimeSpan PairedActionPulseDuration = TimeSpan.FromMilliseconds(300);
|
||||
private const string CirculatingWaterAction = "循环水";
|
||||
private const string SamplingPumpAction = "取样泵";
|
||||
private const string IgniterAction = "点火器";
|
||||
@@ -86,6 +88,8 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
CreateAction(CalibrationStartAction, CalibrationStartAction, "标定结束"),
|
||||
CreateAction(BaselineCollectionAction, BaselineCollectionAction, "基线结束")
|
||||
];
|
||||
_actionsByLabel[CalibrationStartAction].UpdateStatus(false);
|
||||
_actionsByLabel[BaselineCollectionAction].UpdateStatus(false);
|
||||
|
||||
RefreshDeviceValues();
|
||||
_refreshTimer = new DispatcherTimer
|
||||
@@ -168,8 +172,9 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
"BaselineOxygen",
|
||||
BaselineOxygenRegister,
|
||||
OxygenMinimum,
|
||||
OxygenMaximum,
|
||||
"0.00");
|
||||
OxygenMaximum / BaselineOxygenDisplayScale,
|
||||
"0.00",
|
||||
BaselineOxygenDisplayScale);
|
||||
TemperatureText = ReadRangedFloatText(
|
||||
"Temperature",
|
||||
TemperatureRegister,
|
||||
@@ -194,7 +199,7 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
CValueMinimum,
|
||||
CValueMaximum,
|
||||
"0.00");
|
||||
RefreshActionStates();
|
||||
RefreshHoldActionStates();
|
||||
}
|
||||
|
||||
private string ReadRangedFloatText(
|
||||
@@ -202,7 +207,8 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
ushort registerAddress,
|
||||
double minimum,
|
||||
double maximum,
|
||||
string format)
|
||||
string format,
|
||||
double displayScale = 1)
|
||||
{
|
||||
if (!_tcpDeviceConnectionService.TryReadFloatValues(registerAddress, out var result))
|
||||
{
|
||||
@@ -216,7 +222,7 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
}
|
||||
|
||||
LogFloatDiagnostic(label, registerAddress, result, byteOrder, matchCount);
|
||||
return NormalizeDisplayValue(value).ToString(format, CultureInfo.InvariantCulture);
|
||||
return NormalizeDisplayValue(value * displayScale).ToString(format, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
private void LogFloatDiagnostic(
|
||||
@@ -262,15 +268,13 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
return action;
|
||||
}
|
||||
|
||||
private void RefreshActionStates()
|
||||
private void RefreshHoldActionStates()
|
||||
{
|
||||
UpdateActionStatus(CirculatingWaterAction, CirculatingWaterCoil);
|
||||
UpdateActionStatus(MethaneValveAction, MethaneValveCoil);
|
||||
UpdateActionStatus(FanAction, FanCoil);
|
||||
UpdateActionStatus(IgniterAction, IgniterCoil);
|
||||
UpdateActionStatus(SamplingPumpAction, SamplingPumpCoil);
|
||||
UpdateActionStatus(BaselineCollectionAction, BaselineCollectionCoil);
|
||||
UpdateActionStatus(CalibrationStartAction, CalibrationStartCoil);
|
||||
}
|
||||
|
||||
private bool UpdateActionStatus(string action, ushort coilAddress)
|
||||
@@ -327,27 +331,23 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_tcpDeviceConnectionService.TryReadCoil(startCoilAddress, out var isActive))
|
||||
if (!_actionsByLabel.TryGetValue(action, out var actionViewModel))
|
||||
{
|
||||
LastAction = $"{action}状态读取失败";
|
||||
Debug.WriteLine($"C value calibration action '{action}' state read failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
var isActive = actionViewModel.IsActive;
|
||||
var coilAddress = isActive ? endCoilAddress : startCoilAddress;
|
||||
var actionText = isActive ? endActionText : action;
|
||||
|
||||
if (_tcpDeviceConnectionService.TryWriteCoil(coilAddress, true))
|
||||
if (TryStartCoilPulse(coilAddress, actionText))
|
||||
{
|
||||
var completedBaselineCollection = action == BaselineCollectionAction && isActive;
|
||||
var completedCalibration = action == CalibrationStartAction && isActive;
|
||||
LastAction = completedBaselineCollection
|
||||
? "基线采集完成"
|
||||
: completedCalibration ? "标定完成" : actionText;
|
||||
if (_actionsByLabel.TryGetValue(action, out var actionViewModel))
|
||||
{
|
||||
actionViewModel.UpdateStatus(!isActive);
|
||||
}
|
||||
actionViewModel.UpdateStatus(!isActive);
|
||||
|
||||
if (completedBaselineCollection)
|
||||
{
|
||||
@@ -366,6 +366,26 @@ public sealed class CValueCalibrationViewModel : PageViewModel
|
||||
Debug.WriteLine($"C value calibration action '{actionText}' write failed.");
|
||||
}
|
||||
|
||||
private bool TryStartCoilPulse(ushort coilAddress, string actionText)
|
||||
{
|
||||
if (!_tcpDeviceConnectionService.TryWriteCoil(coilAddress, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_ = ReleaseCoilAfterPulseAsync(coilAddress, actionText);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task ReleaseCoilAfterPulseAsync(ushort coilAddress, string actionText)
|
||||
{
|
||||
await Task.Delay(PairedActionPulseDuration);
|
||||
if (!_tcpDeviceConnectionService.TryWriteCoil(coilAddress, false))
|
||||
{
|
||||
Debug.WriteLine($"C value calibration action '{actionText}' pulse release failed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryGetHoldActionCoil(string action, out ushort coilAddress)
|
||||
{
|
||||
switch (action)
|
||||
|
||||
@@ -18,6 +18,8 @@ public sealed class ConeRadiationSettingsViewModel : PageViewModel
|
||||
private const double CurrentTemperatureMaximumDropPerRefresh = 80;
|
||||
private const double CurrentHeatFluxMinimum = 0;
|
||||
private const double CurrentHeatFluxMaximum = 1000;
|
||||
private const double CurrentHeatFluxStableTolerance = 5;
|
||||
private const int CurrentHeatFluxStableReadCount = 3;
|
||||
private const double HeatTransferInputMinimum = 0;
|
||||
private const double HeatTransferReadMinimum = 0.01;
|
||||
private const double HeatTransferMaximum = 20000;
|
||||
@@ -44,6 +46,9 @@ public sealed class ConeRadiationSettingsViewModel : PageViewModel
|
||||
private bool _heatingActive;
|
||||
private bool _isEditingConeParameters;
|
||||
private double? _lastStableCurrentTemperature;
|
||||
private double? _lastStableCurrentHeatFlux;
|
||||
private double? _pendingCurrentHeatFlux;
|
||||
private int _pendingCurrentHeatFluxReadCount;
|
||||
private DateTime _parameterRefreshBlockedUntil = DateTime.MinValue;
|
||||
|
||||
public ConeRadiationSettingsViewModel(
|
||||
@@ -191,10 +196,17 @@ public sealed class ConeRadiationSettingsViewModel : PageViewModel
|
||||
CurrentHeatFluxMinimum,
|
||||
CurrentHeatFluxMaximum,
|
||||
"0.00",
|
||||
out var currentHeatFluxText,
|
||||
out _))
|
||||
out _,
|
||||
out var currentHeatFlux))
|
||||
{
|
||||
CurrentHeatFluxText = currentHeatFluxText;
|
||||
if (TryUpdateStableCurrentHeatFlux(currentHeatFlux, out var stableCurrentHeatFlux))
|
||||
{
|
||||
CurrentHeatFluxText = stableCurrentHeatFlux.ToString("0.00", CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
else if (!_lastStableCurrentHeatFlux.HasValue)
|
||||
{
|
||||
CurrentHeatFluxText = string.Empty;
|
||||
}
|
||||
|
||||
if (CanRefreshConeParameters())
|
||||
@@ -271,6 +283,46 @@ public sealed class ConeRadiationSettingsViewModel : PageViewModel
|
||||
|| value >= _lastStableCurrentTemperature.Value - CurrentTemperatureMaximumDropPerRefresh;
|
||||
}
|
||||
|
||||
private bool TryUpdateStableCurrentHeatFlux(double value, out double stableValue)
|
||||
{
|
||||
value = NormalizeDisplayValue(value);
|
||||
stableValue = _lastStableCurrentHeatFlux ?? value;
|
||||
|
||||
if (_lastStableCurrentHeatFlux.HasValue
|
||||
&& Math.Abs(value - _lastStableCurrentHeatFlux.Value) <= CurrentHeatFluxStableTolerance)
|
||||
{
|
||||
AcceptStableCurrentHeatFlux(value);
|
||||
stableValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_pendingCurrentHeatFlux.HasValue
|
||||
|| Math.Abs(value - _pendingCurrentHeatFlux.Value) > CurrentHeatFluxStableTolerance)
|
||||
{
|
||||
_pendingCurrentHeatFlux = value;
|
||||
_pendingCurrentHeatFluxReadCount = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
_pendingCurrentHeatFluxReadCount++;
|
||||
|
||||
if (_pendingCurrentHeatFluxReadCount < CurrentHeatFluxStableReadCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AcceptStableCurrentHeatFlux(value);
|
||||
stableValue = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AcceptStableCurrentHeatFlux(double value)
|
||||
{
|
||||
_lastStableCurrentHeatFlux = value;
|
||||
_pendingCurrentHeatFlux = null;
|
||||
_pendingCurrentHeatFluxReadCount = 0;
|
||||
}
|
||||
|
||||
private string ReadScaledInt16Text(ushort registerAddress, double scale, string format)
|
||||
{
|
||||
return _tcpDeviceConnectionService.TryReadInt16(registerAddress, out var rawValue)
|
||||
|
||||
Reference in New Issue
Block a user