using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using HME_MoistureLossMeter.Services; using System.Threading.Tasks; using System.Windows; using Serilog; namespace HME_MoistureLossMeter.ViewModels { public partial class ManualControlViewModel : ViewModelBase { private readonly IPlcService _plcService; [ObservableProperty] private float _manualSpeed; [ObservableProperty] private float _tidalCoeff; [ObservableProperty] private float _freqCoeff; [ObservableProperty] private bool _isConnected; public ManualControlViewModel(IPlcService plcService) { _plcService = plcService; // 启动时读取参数 Task.Run(async () => await ReadParameters()); } private async Task ReadParameters() { try { if (!_plcService.IsConnected) await _plcService.EnsureConnectedAsync(); ManualSpeed = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_MANUAL_SPEED); TidalCoeff = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_TIDAL_COEFF); FreqCoeff = await _plcService.ReadFloatAsync(ModbusTcpPlcService.ADDR_FREQ_COEFF); IsConnected = true; StatusMessage = "参数读取成功"; } catch (Exception ex) { IsConnected = false; StatusMessage = $"读取参数失败: {ex.Message}"; Log.Error(ex, "读取手动参数失败"); } } [RelayCommand] private async Task SaveParameters() { try { IsBusy = true; await _plcService.WriteMultipleRegistersAsync(ModbusTcpPlcService.ADDR_MANUAL_SPEED, ManualSpeed); await _plcService.WriteMultipleRegistersAsync(ModbusTcpPlcService.ADDR_TIDAL_COEFF, TidalCoeff); await _plcService.WriteMultipleRegistersAsync(ModbusTcpPlcService.ADDR_FREQ_COEFF, FreqCoeff); StatusMessage = "参数保存成功"; Log.Information("手动参数已保存"); } catch (Exception ex) { StatusMessage = $"保存参数失败: {ex.Message}"; Log.Error(ex, "保存手动参数失败"); MessageBox.Show($"保存参数失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { IsBusy = false; } } [RelayCommand] private async Task ManualInhale() { await ExecuteCoilCommand(ModbusTcpPlcService.COIL_MANUAL_INHALE, "手动吸气"); } [RelayCommand] private async Task ManualExhale() { await ExecuteCoilCommand(ModbusTcpPlcService.COIL_MANUAL_EXHALE, "手动呼气"); } [RelayCommand] private async Task MoveLeft() { await ExecuteCoilCommand(ModbusTcpPlcService.COIL_LEFT, "左移"); } [RelayCommand] private async Task MoveRight() { await ExecuteCoilCommand(ModbusTcpPlcService.COIL_RIGHT, "右移"); } [RelayCommand] private async Task MoveUp() { await ExecuteCoilCommand(ModbusTcpPlcService.COIL_UP, "上升"); } [RelayCommand] private async Task MoveDown() { await ExecuteCoilCommand(ModbusTcpPlcService.COIL_DOWN, "下降"); } [RelayCommand] private async Task ZeroCalibration() { try { IsBusy = true; await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_ZERO, true); StatusMessage = "校零已触发"; Log.Information("校零触发"); // 等待完成后自动复位 await Task.Delay(2000); await _plcService.WriteCoilAsync(ModbusTcpPlcService.COIL_ZERO, false); StatusMessage = "校零完成"; } catch (Exception ex) { StatusMessage = $"校零失败: {ex.Message}"; Log.Error(ex, "校零失败"); MessageBox.Show($"校零失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { IsBusy = false; } } private async Task ExecuteCoilCommand(ushort coilAddress, string commandName) { try { IsBusy = true; await _plcService.WriteCoilAsync(coilAddress, true); StatusMessage = $"{commandName}已执行"; Log.Information("{Command}执行", commandName); // 短暂延迟后自动复位 await Task.Delay(200); await _plcService.WriteCoilAsync(coilAddress, false); } catch (Exception ex) { StatusMessage = $"{commandName}失败: {ex.Message}"; Log.Error(ex, "{Command}失败", commandName); MessageBox.Show($"{commandName}失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { IsBusy = false; } } [RelayCommand] private async Task RefreshParameters() { await ReadParameters(); } } }