Files
ConeCalorimeter/ConeCalorimeter/ViewModels/ConeRadiationSettingsViewModel.cs
GukSang.Jin 6bc1475ae6 更新数据
2026-05-21 16:44:02 +08:00

281 lines
8.5 KiB
C#

using System.Diagnostics;
using System.Globalization;
using System.Windows.Threading;
using CommunityToolkit.Mvvm.Input;
using ConeCalorimeter.Services;
namespace ConeCalorimeter.ViewModels;
public sealed class ConeRadiationSettingsViewModel : PageViewModel
{
private const ushort CurrentTemperatureRegister = 26;
private const ushort TargetTemperatureRegister = 400;
private const ushort CurrentHeatFluxRegister = 32;
private const ushort SlopeRegister = 420;
private const ushort InterceptRegister = 422;
private const ushort AlarmCoil = 91;
private const ushort CirculatingWaterCoil = 49;
private const string CirculatingWaterAction = "循环水";
private readonly Action _closeAction;
private readonly Action _helpAction;
private readonly ITcpDeviceConnectionService _tcpDeviceConnectionService;
private readonly DispatcherTimer _refreshTimer;
private string _currentTemperatureText = "";
private string _currentHeatFluxText = "";
private string _targetTemperatureText = "";
private string _heatTransferText = "";
private string _slopeText = "";
private string _interceptText = "";
private string _lastAction = "待机";
private bool _alarmActive;
private bool _circulatingWaterActive;
private bool _isEditingConeParameters;
public ConeRadiationSettingsViewModel(
Action closeAction,
Action helpAction,
ITcpDeviceConnectionService tcpDeviceConnectionService) : base("辐射锥设置")
{
_closeAction = closeAction;
_helpAction = helpAction;
_tcpDeviceConnectionService = tcpDeviceConnectionService;
CloseCommand = new RelayCommand(_closeAction);
HelpCommand = new RelayCommand(_helpAction);
ActionCommand = new RelayCommand<string>(ExecuteAction);
SaveParametersCommand = new RelayCommand(SaveParameters);
RefreshDeviceValues();
_refreshTimer = new DispatcherTimer
{
Interval = TimeSpan.FromSeconds(1)
};
_refreshTimer.Tick += (_, _) => RefreshDeviceValues();
_refreshTimer.Start();
}
public IRelayCommand CloseCommand { get; }
public IRelayCommand HelpCommand { get; }
public IRelayCommand<string> ActionCommand { get; }
public IRelayCommand SaveParametersCommand { get; }
public string CurrentTemperatureText
{
get => _currentTemperatureText;
private set => SetProperty(ref _currentTemperatureText, value);
}
public string CurrentHeatFluxText
{
get => _currentHeatFluxText;
private set => SetProperty(ref _currentHeatFluxText, value);
}
public string TargetTemperatureText
{
get => _targetTemperatureText;
set => SetProperty(ref _targetTemperatureText, value);
}
public string HeatTransferText
{
get => _heatTransferText;
set => SetProperty(ref _heatTransferText, value);
}
public string SlopeText
{
get => _slopeText;
set => SetProperty(ref _slopeText, value);
}
public string InterceptText
{
get => _interceptText;
set => SetProperty(ref _interceptText, value);
}
public string LastAction
{
get => _lastAction;
private set => SetProperty(ref _lastAction, value);
}
public bool AlarmActive
{
get => _alarmActive;
private set => SetProperty(ref _alarmActive, value);
}
public bool CirculatingWaterActive
{
get => _circulatingWaterActive;
private set
{
if (SetProperty(ref _circulatingWaterActive, value))
{
OnPropertyChanged(nameof(CirculatingWaterButtonText));
}
}
}
public string CirculatingWaterButtonText => CirculatingWaterActive ? "循环水:开启" : "循环水:关闭";
public void BeginConeParameterEdit()
{
_isEditingConeParameters = true;
}
public void EndConeParameterEdit()
{
_isEditingConeParameters = false;
}
private void ExecuteAction(string? action)
{
if (string.IsNullOrWhiteSpace(action))
{
return;
}
LastAction = action;
if (action == CirculatingWaterAction)
{
ToggleCirculatingWater();
return;
}
if (action == "开始升温")
{
WriteTargetTemperature();
WriteActionCoil(action);
return;
}
WriteActionCoil(action);
}
private void RefreshDeviceValues()
{
CurrentTemperatureText = ReadFloatText(CurrentTemperatureRegister);
CurrentHeatFluxText = ReadFloatText(CurrentHeatFluxRegister);
if (!_isEditingConeParameters)
{
SlopeText = ReadFloatText(SlopeRegister);
InterceptText = ReadFloatText(InterceptRegister);
}
AlarmActive = _tcpDeviceConnectionService.TryReadCoil(AlarmCoil, out var alarmActive) && alarmActive;
if (_tcpDeviceConnectionService.TryReadCoil(CirculatingWaterCoil, out var circulatingWaterActive))
{
CirculatingWaterActive = circulatingWaterActive;
}
}
private string ReadFloatText(ushort registerAddress)
{
return _tcpDeviceConnectionService.TryReadFloat(registerAddress, out var value)
? value.ToString("0.00", CultureInfo.InvariantCulture)
: string.Empty;
}
private void WriteTargetTemperature()
{
if (!short.TryParse(TargetTemperatureText, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value))
{
Debug.WriteLine($"Invalid cone radiation target temperature: {TargetTemperatureText}");
return;
}
if (!_tcpDeviceConnectionService.TryWriteInt16(TargetTemperatureRegister, value))
{
LastAction = "设置辐射温度失败";
Debug.WriteLine("Cone radiation target temperature write failed.");
}
}
private void SaveParameters()
{
if (!float.TryParse(SlopeText, NumberStyles.Float, CultureInfo.InvariantCulture, out var slope))
{
LastAction = "斜率输入无效";
Debug.WriteLine($"Invalid cone radiation slope: {SlopeText}");
return;
}
if (!float.TryParse(InterceptText, NumberStyles.Float, CultureInfo.InvariantCulture, out var intercept))
{
LastAction = "截距输入无效";
Debug.WriteLine($"Invalid cone radiation intercept: {InterceptText}");
return;
}
var slopeWritten = _tcpDeviceConnectionService.TryWriteFloat(SlopeRegister, slope);
var interceptWritten = _tcpDeviceConnectionService.TryWriteFloat(InterceptRegister, intercept);
if (slopeWritten && interceptWritten)
{
LastAction = "参数保存成功";
return;
}
LastAction = "参数保存失败";
Debug.WriteLine($"Cone radiation parameters write failed. Slope: {slopeWritten}, intercept: {interceptWritten}.");
}
private void ToggleCirculatingWater()
{
if (!_tcpDeviceConnectionService.TryReadCoil(CirculatingWaterCoil, out var isActive))
{
LastAction = "循环水状态读取失败";
Debug.WriteLine("Cone radiation circulating water state read failed.");
return;
}
var nextValue = !isActive;
if (_tcpDeviceConnectionService.TryWriteCoil(CirculatingWaterCoil, nextValue))
{
CirculatingWaterActive = nextValue;
LastAction = $"循环水{(nextValue ? "" : "")}";
return;
}
LastAction = $"循环水{(nextValue ? "" : "")}失败";
Debug.WriteLine("Cone radiation circulating water write failed.");
}
private void WriteActionCoil(string action)
{
if (!TryGetActionCoil(action, out var coilAddress))
{
return;
}
if (!_tcpDeviceConnectionService.TryWriteCoil(coilAddress, true))
{
LastAction = $"{action}失败";
Debug.WriteLine($"Cone radiation action '{action}' write failed.");
}
}
private static bool TryGetActionCoil(string action, out ushort coilAddress)
{
switch (action)
{
case "开始升温":
coilAddress = 100;
return true;
case "停止升温":
coilAddress = 101;
return true;
default:
coilAddress = 0;
return false;
}
}
}