diff --git a/ConeCalorimeter/ViewModels/CValueCalibrationViewModel.cs b/ConeCalorimeter/ViewModels/CValueCalibrationViewModel.cs index f7af567..1043a48 100644 --- a/ConeCalorimeter/ViewModels/CValueCalibrationViewModel.cs +++ b/ConeCalorimeter/ViewModels/CValueCalibrationViewModel.cs @@ -10,9 +10,10 @@ namespace ConeCalorimeter.ViewModels; public sealed class CValueCalibrationViewModel : PageViewModel { + private const ushort BaselineOxygenRegister = 280; private const ushort TemperatureRegister = 282; private const ushort PressureDifferenceRegister = 284; - private const ushort OxygenRegister = 286; + private const ushort CalibrationOxygenRegister = 286; private const ushort CValueRegister = 308; private const ushort CirculatingWaterCoil = 49; private const ushort SamplingPumpCoil = 50; @@ -147,12 +148,10 @@ public sealed class CValueCalibrationViewModel : PageViewModel private void RefreshDeviceValues() { - var oxygenText = ReadFloatText(OxygenRegister); - - BaselineOxygenText = oxygenText; + BaselineOxygenText = ReadFloatText(BaselineOxygenRegister); TemperatureText = ReadFloatText(TemperatureRegister); PressureDifferenceText = ReadFloatText(PressureDifferenceRegister); - CalibrationOxygenText = oxygenText; + CalibrationOxygenText = ReadFloatText(CalibrationOxygenRegister); CValueText = ReadFloatText(CValueRegister); RefreshActionStates(); } diff --git a/ConeCalorimeter/ViewModels/DeviceActionViewModel.cs b/ConeCalorimeter/ViewModels/DeviceActionViewModel.cs index af1db85..8c561e1 100644 --- a/ConeCalorimeter/ViewModels/DeviceActionViewModel.cs +++ b/ConeCalorimeter/ViewModels/DeviceActionViewModel.cs @@ -1,16 +1,31 @@ using System.Windows.Input; +using CommunityToolkit.Mvvm.ComponentModel; namespace ConeCalorimeter.ViewModels; -public sealed class DeviceActionViewModel +public sealed class DeviceActionViewModel : ObservableObject { + private string _displayText; + public DeviceActionViewModel(string label, ICommand command) { Label = label; Command = command; + _displayText = label; } public string Label { get; } + public string DisplayText + { + get => _displayText; + private set => SetProperty(ref _displayText, value); + } + public ICommand Command { get; } + + public void SetDisplayText(string displayText) + { + DisplayText = displayText; + } } diff --git a/ConeCalorimeter/ViewModels/TestPageViewModel.cs b/ConeCalorimeter/ViewModels/TestPageViewModel.cs index b8a2d69..0d88a3c 100644 --- a/ConeCalorimeter/ViewModels/TestPageViewModel.cs +++ b/ConeCalorimeter/ViewModels/TestPageViewModel.cs @@ -1,5 +1,6 @@ using System.Collections.ObjectModel; using System.Diagnostics; +using System.Windows.Threading; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using ConeCalorimeter.Models; @@ -13,12 +14,19 @@ namespace ConeCalorimeter.ViewModels; public sealed class TestPageViewModel : PageViewModel { + private const string ResetAction = "复位"; + private const ushort ResetCoil = 80; + private const ushort ResetCompleteCoil = 82; + private readonly IExperimentDataService _experimentDataService; private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService; private readonly LineSeries _heatReleaseSeries; private readonly LineSeries _totalHeatSeries; private readonly LineSeries _totalSmokeSeries; + private readonly DispatcherTimer _resetStatusTimer; + private DeviceActionViewModel _resetAction = null!; private bool _flameDetected; + private bool _resetInProgress; private string _lastAction = "待机"; public TestPageViewModel( @@ -62,6 +70,7 @@ public sealed class TestPageViewModel : PageViewModel ]; ExecuteDeviceActionCommand = new RelayCommand(ExecuteDeviceAction); + _resetAction = new DeviceActionViewModel(ResetAction, ExecuteDeviceActionCommand); DeviceActions = [ new DeviceActionViewModel("辐射锥升", ExecuteDeviceActionCommand), @@ -73,12 +82,19 @@ public sealed class TestPageViewModel : PageViewModel new DeviceActionViewModel("风机开", ExecuteDeviceActionCommand), new DeviceActionViewModel("风机关", ExecuteDeviceActionCommand), new DeviceActionViewModel("点火关", ExecuteDeviceActionCommand), - new DeviceActionViewModel("复位", ExecuteDeviceActionCommand) + _resetAction ]; HeatReleasePlot = CreatePlotModel(out _heatReleaseSeries, out _totalHeatSeries, out _totalSmokeSeries); UpdateSnapshot(_experimentDataService.CurrentSnapshot); _experimentDataService.SnapshotUpdated += (_, snapshot) => UpdateSnapshot(snapshot); + + _resetStatusTimer = new DispatcherTimer + { + Interval = TimeSpan.FromSeconds(1) + }; + _resetStatusTimer.Tick += (_, _) => RefreshResetStatus(); + _resetStatusTimer.Start(); } public ObservableCollection TopMetrics { get; } @@ -287,6 +303,12 @@ public sealed class TestPageViewModel : PageViewModel LastAction = action; + if (action == ResetAction) + { + ExecuteResetAction(); + return; + } + if (action == "测试开始") { _experimentDataService.StartTest(); @@ -308,6 +330,40 @@ public sealed class TestPageViewModel : PageViewModel } } + private void ExecuteResetAction() + { + if (!_tcpDeviceConnectionService.TryWriteCoil(ResetCoil, true)) + { + LastAction = "复位失败"; + Debug.WriteLine("Device reset write failed."); + return; + } + + SetResetInProgress(true); + } + + private void RefreshResetStatus() + { + if (!_resetInProgress) + { + return; + } + + if (!_tcpDeviceConnectionService.TryReadCoil(ResetCompleteCoil, out var resetComplete) || !resetComplete) + { + return; + } + + SetResetInProgress(false); + LastAction = "复位完成"; + } + + private void SetResetInProgress(bool resetInProgress) + { + _resetInProgress = resetInProgress; + _resetAction.SetDisplayText(resetInProgress ? "复位中" : ResetAction); + } + private void ClearPlotSeries() { _heatReleaseSeries.Points.Clear(); @@ -325,9 +381,6 @@ public sealed class TestPageViewModel : PageViewModel switch (action) { - case "复位": - coilAddress = 88; - return true; case "测试开始": coilAddress = 65; return true; diff --git a/ConeCalorimeter/Views/TestPageView.xaml b/ConeCalorimeter/Views/TestPageView.xaml index 29df73c..f67a2f7 100644 --- a/ConeCalorimeter/Views/TestPageView.xaml +++ b/ConeCalorimeter/Views/TestPageView.xaml @@ -211,7 +211,7 @@ -