using DeviceCommand.Base; using DeviceCommand.Devices; using MainModule.Events; using MainModule.Views; using Model.Entity; using Prism.Commands; using Prism.Events; using Prism.Ioc; using Prism.Navigation; using System.Collections.ObjectModel; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Threading; using UIShare.ViewModelBase; namespace MainModule.ViewModels { public class MainViewModel : NavigateViewModelBase { private readonly THC1100 _thc1100 = new(); private readonly UMC1300 _umc1300; public ObservableCollection Chambers { get; } = new(); private IContainerProvider _containerProvider; private CancellationTokenSource _refreshCts; private DispatcherTimer _refreshTimer; private bool _isInitialized = false; #region 按钮文本和连接状态 private string _connectButtonText = "连接设备"; public string ConnectButtonText { get => _connectButtonText; set => SetProperty(ref _connectButtonText, value); } private bool _isConnected = false; public bool IsConnected { get => _isConnected; set { if (SetProperty(ref _isConnected, value)) { ConnectButtonText = value ? "断开连接" : "连接设备"; } } } #endregion #region 命令定义 public DelegateCommand ConnectCommand { get; } public DelegateCommand DisconnectCommand { get; } public DelegateCommand RefreshCommand { get; } public DelegateCommand ConfigCommand { get; } public DelegateCommand ConnectDeviceCommand { get; } #endregion #region 配置信息 private Events.ProtocolType _selectedProtocol = Events.ProtocolType.S7; public Events.ProtocolType SelectedProtocol { get => _selectedProtocol; set => SetProperty(ref _selectedProtocol, value); } private string _configIpAddress = "127.0.0.1"; public string ConfigIpAddress { get => _configIpAddress; set => SetProperty(ref _configIpAddress, value); } private int _configPort = 102; public int ConfigPort { get => _configPort; set => SetProperty(ref _configPort, value); } private S7.Net.CpuType _configCpuType = S7.Net.CpuType.S71200; public S7.Net.CpuType ConfigCpuType { get => _configCpuType; set => SetProperty(ref _configCpuType, value); } private short _configRack = 0; public short ConfigRack { get => _configRack; set => SetProperty(ref _configRack, value); } private short _configSlot = 1; public short ConfigSlot { get => _configSlot; set => SetProperty(ref _configSlot, value); } private string _configSerialPort = "COM1"; public string ConfigSerialPort { get => _configSerialPort; set => SetProperty(ref _configSerialPort, value); } private int _configBaudRate = 9600; public int ConfigBaudRate { get => _configBaudRate; set => SetProperty(ref _configBaudRate, value); } private int _configSendTimeout = 3000; public int ConfigSendTimeout { get => _configSendTimeout; set => SetProperty(ref _configSendTimeout, value); } private int _configReceiveTimeout = 5000; public int ConfigReceiveTimeout { get => _configReceiveTimeout; set => SetProperty(ref _configReceiveTimeout, value); } #endregion public MainViewModel(IContainerProvider containerProvider) : base(containerProvider) { _containerProvider = containerProvider; // 初始化UMC1300设备(默认从站地址1) _umc1300 = new UMC1300(1, "127.0.0.1", 502); // 初始化命令 ConnectCommand = new DelegateCommand(async () => await ExecuteConnectAsync()); DisconnectCommand = new DelegateCommand(ExecuteDisconnect); RefreshCommand = new DelegateCommand(async () => await RefreshDeviceDataAsync()); ConfigCommand = new DelegateCommand(() => ShowConfigDialogAsync()); ConnectDeviceCommand = new DelegateCommand(async (item) => await ExecuteConnectDeviceAsync(item)); } /// /// 当视图被导航到时执行初始化(Prism导航机制) /// public override async void OnNavigatedTo(NavigationContext navigationContext) { base.OnNavigatedTo(navigationContext); // 避免重复初始化 if (_isInitialized) return; _isInitialized = true; await InitializeAsync(); } /// /// 异步初始化设备连接和数据 /// private async Task InitializeAsync() { try { // 先添加所有卡片(显示初始状态) Application.Current.Dispatcher.Invoke(() => { Chambers.Clear(); Chambers.Add(new ChamberMonitorItem { Id = 1, Name = "环境箱 01", ProtocolType = "Modbus TCP", IsConnected = false, Temperature = 0.0, Humidity = 0.0 }); Chambers.Add(new ChamberMonitorItem { Id = 2, Name = "环境箱 02", ProtocolType = "Modbus TCP B+", IsConnected = false, Temperature = 0.0, Humidity = 0.0 }); Chambers.Add(new ChamberMonitorItem { Id = 3, Name = "环境箱 03", ProtocolType = "S7", IsConnected = false, Temperature = 0.0, Humidity = 0.0 }); Chambers.Add(new ChamberMonitorItem { Id = 4, Name = "环境箱 04", ProtocolType = "HTTP", IsConnected = false, Temperature = 0.0, Humidity = 0.0 }); }); System.Diagnostics.Debug.WriteLine("设备卡片初始化完成"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"初始化异常: {ex.Message}"); } } #region 配置对话框 /// /// 显示配置连接对话框 /// private void ShowConfigDialogAsync() { try { // 手动创建 ViewModel var viewModel = new ConnectionConfigViewModel(); // 设置初始值 viewModel.SelectedProtocol = SelectedProtocol; viewModel.IpAddress = ConfigIpAddress; viewModel.Port = ConfigPort; viewModel.CpuType = ConfigCpuType; viewModel.Rack = ConfigRack; viewModel.Slot = ConfigSlot; viewModel.SerialPort = ConfigSerialPort; viewModel.BaudRate = ConfigBaudRate; viewModel.SendTimeout = ConfigSendTimeout; viewModel.ReceiveTimeout = ConfigReceiveTimeout; // 创建窗口 var configWindow = new ConnectionConfigView(viewModel); // 设置父窗口 configWindow.Owner = Application.Current.MainWindow; // 显示模态对话框 bool? result = configWindow.ShowDialog(); // 如果用户点击确定,获取配置数据 if (result == true && viewModel.ConnectionConfigData != null) { // 直接更新配置参数 SelectedProtocol = viewModel.ConnectionConfigData.Protocol; ConfigIpAddress = viewModel.ConnectionConfigData.IpAddress; ConfigPort = viewModel.ConnectionConfigData.Port; ConfigCpuType = viewModel.ConnectionConfigData.CpuType; ConfigRack = viewModel.ConnectionConfigData.Rack; ConfigSlot = viewModel.ConnectionConfigData.Slot; ConfigSerialPort = viewModel.ConnectionConfigData.SerialPort; ConfigBaudRate = viewModel.ConnectionConfigData.BaudRate; ConfigSendTimeout = viewModel.ConnectionConfigData.SendTimeout; ConfigReceiveTimeout = viewModel.ConnectionConfigData.ReceiveTimeout; System.Diagnostics.Debug.WriteLine($"配置更新成功: 协议={SelectedProtocol}, IP={ConfigIpAddress}, 端口={ConfigPort}"); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"打开配置对话框异常: {ex.Message}"); } } /// /// 配置更新事件处理 /// private void OnConfigUpdated(ConnectionConfigEvent.ConnectionConfigData config) { SelectedProtocol = config.Protocol; ConfigIpAddress = config.IpAddress; ConfigPort = config.Port; ConfigCpuType = config.CpuType; ConfigRack = config.Rack; ConfigSlot = config.Slot; ConfigSerialPort = config.SerialPort; ConfigBaudRate = config.BaudRate; ConfigSendTimeout = config.SendTimeout; ConfigReceiveTimeout = config.ReceiveTimeout; System.Diagnostics.Debug.WriteLine($"配置更新: 协议={SelectedProtocol}, IP={ConfigIpAddress}, 端口={ConfigPort}"); } #endregion #region 连接命令实现 /// /// 执行连接/断开切换命令 /// private async Task ExecuteConnectAsync() { if (IsConnected) { // 如果已连接,则断开 ExecuteDisconnect(); } else { // 如果未连接,则连接 await ConnectToDeviceAsync(); } } /// /// 连接到THC设备 /// private async Task ConnectToDeviceAsync() { try { System.Diagnostics.Debug.WriteLine("正在连接THC设备..."); // 使用配置对话框中设置的参数配置设备 _thc1100.ConfigureDevice( ipAddress: ConfigIpAddress, cpuType: ConfigCpuType, rack: ConfigRack, slot: ConfigSlot ); System.Diagnostics.Debug.WriteLine($"配置参数: 协议={SelectedProtocol}, IP={_thc1100.IPAddress}, CPU={_thc1100.CpuType}, Rack={_thc1100.Rack}, Slot={_thc1100.Slot}"); // 连接THC设备 bool connected = await _thc1100.ConnectAsync(); if (connected) { IsConnected = true; System.Windows.MessageBox.Show("THC设备连接成功", "连接成功", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information); // 更新环境箱03的连接状态 var chamber3 = GetChamberById(3); if (chamber3 != null) { chamber3.IsConnected = true; } // 读取初始数据 await RefreshDeviceDataAsync(); // 启动定时刷新(每1秒) StartPeriodicRefresh(); } else { System.Diagnostics.Debug.WriteLine("THC设备连接失败"); MessageBox.Show("设备连接失败,请检查网络和设备状态!", "连接失败", MessageBoxButton.OK, MessageBoxImage.Warning); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"连接异常: {ex.Message}"); MessageBox.Show($"连接异常: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } /// /// 断开THC设备连接 /// private void ExecuteDisconnect() { try { // 停止定时器 _refreshCts?.Cancel(); _refreshTimer?.Stop(); // 关闭设备连接 _thc1100.Close(); // 更新连接状态 IsConnected = false; // 更新环境箱03的连接状态 var chamber3 = GetChamberById(3); if (chamber3 != null) { chamber3.IsConnected = false; } System.Diagnostics.Debug.WriteLine("THC设备已断开连接"); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"断开连接异常: {ex.Message}"); } } #endregion #region 定时刷新 /// /// 启动定时刷新 /// private void StartPeriodicRefresh() { _refreshCts?.Cancel(); _refreshCts = new CancellationTokenSource(); _refreshTimer?.Stop(); _refreshTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; _refreshTimer.Tick += async (s, e) => { try { System.Diagnostics.Debug.WriteLine($"[定时刷新] Tick触发,当前时间: {DateTime.Now:HH:mm:ss.fff}"); System.Diagnostics.Debug.WriteLine($"[定时刷新] THC1100.IsConnected = {_thc1100.IsConnected}"); // 检查THC1100连接状态 if (_thc1100.IsConnected) { var chamber3 = GetChamberById(3); System.Diagnostics.Debug.WriteLine($"[定时刷新] chamber3 = {chamber3}, IsConnected = {chamber3?.IsConnected}"); if (chamber3 != null) { System.Diagnostics.Debug.WriteLine("[定时刷新] 开始读取温湿度数据..."); try { var temp = await _thc1100.GetRealTimeTemperatureSetPointAsync(); var humidity = await _thc1100.GetRealTimeHumidityMeasuredValueAsync(); System.Diagnostics.Debug.WriteLine($"[定时刷新] 读取完成 - 温度(DB53.DBD280): {temp}, 湿度(DB53.DBD1092): {humidity}"); Application.Current.Dispatcher.Invoke(() => { chamber3.Temperature = temp; chamber3.Humidity = humidity; System.Diagnostics.Debug.WriteLine($"[定时刷新] UI已更新 - Temperature={chamber3.Temperature}, Humidity={chamber3.Humidity}"); }); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[定时刷新] 读取温湿度数据异常: {ex.Message}"); } } } else { System.Diagnostics.Debug.WriteLine("[定时刷新] THC1100未连接,跳过数据读取"); } // 检查UMC1300连接状态 if (_umc1300.IsConnected) { var chamber1 = GetChamberById(1); if (chamber1 != null) { try { var temp = await _umc1300.ReadTemperaturePVAsync(); var humidity = await _umc1300.ReadHumidityPVAsync(); Application.Current.Dispatcher.Invoke(() => { chamber1.Temperature = temp; chamber1.Humidity = humidity; }); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[定时刷新] 读取UMC1300数据异常: {ex.Message}"); } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[定时刷新] 定时器异常: {ex.Message}"); } }; _refreshTimer.Start(); } /// /// 停止定时刷新 /// private void StopPeriodicRefresh() { _refreshCts?.Cancel(); _refreshTimer?.Stop(); } #endregion #region 数据刷新 /// /// 刷新设备数据 /// private async Task RefreshDeviceDataAsync() { try { // 如果未连接,不刷新数据 if (!_thc1100.IsConnected) return; var chamber3 = GetChamberById(3); if (chamber3 == null) return; // 读取温湿度数据(使用用户指定的寄存器地址) // 温度: DB53.DBD280, 湿度: DB53.DBD1092 var temp = await _thc1100.GetRealTimeTemperatureSetPointAsync(); var humidity = await _thc1100.GetRealTimeHumidityMeasuredValueAsync(); System.Diagnostics.Debug.WriteLine($"[初始刷新] 环境箱3 - 温度(DB53.DBD280): {temp}, 湿度(DB53.DBD1092): {humidity}"); // 更新UI(在UI线程执行) Application.Current.Dispatcher.Invoke(() => { chamber3.Temperature = temp; chamber3.Humidity = humidity; }); } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"刷新数据异常: {ex.Message}"); } } #endregion #region 辅助方法 /// /// 根据ID获取卡片 /// private ChamberMonitorItem GetChamberById(int id) { foreach (var chamber in Chambers) { if (chamber.Id == id) return chamber; } return null; } /// /// 根据设备类型连接单个设备 /// private async Task ExecuteConnectDeviceAsync(ChamberMonitorItem item) { if (item == null) return; try { if (item.IsConnected) { // 断开连接 System.Diagnostics.Debug.WriteLine($"[连接] 正在断开设备 {item.Name}"); // 根据设备自己的协议类型调用对应设备的Close方法 switch (item.ProtocolType) { case "S7": _thc1100.Close(); break; case "Modbus TCP": _umc1300.Close(); break; } // 停止数据刷新 StopPeriodicRefresh(); item.IsConnected = false; System.Diagnostics.Debug.WriteLine($"[连接] 设备 {item.Name} 已断开连接"); } else { // 输出当前配置参数 System.Diagnostics.Debug.WriteLine($"[连接] ========== 开始连接设备 {item.Name} =========="); System.Diagnostics.Debug.WriteLine($"[连接] 当前协议类型: {SelectedProtocol}"); System.Diagnostics.Debug.WriteLine($"[连接] IP地址: {ConfigIpAddress}"); System.Diagnostics.Debug.WriteLine($"[连接] 端口: {ConfigPort}"); System.Diagnostics.Debug.WriteLine($"[连接] CPU类型: {ConfigCpuType}"); System.Diagnostics.Debug.WriteLine($"[连接] Rack: {ConfigRack}, Slot: {ConfigSlot}"); System.Diagnostics.Debug.WriteLine($"[连接] 串口: {ConfigSerialPort}, 波特率: {ConfigBaudRate}"); System.Diagnostics.Debug.WriteLine($"[连接] 发送超时: {ConfigSendTimeout}ms, 接收超时: {ConfigReceiveTimeout}ms"); // 根据设备自己的协议类型连接设备 bool connected = false; System.Diagnostics.Debug.WriteLine($"[连接] 设备协议类型: {item.ProtocolType}"); switch (item.ProtocolType) { case "S7": // S7协议连接 System.Diagnostics.Debug.WriteLine("[连接] 使用设备配置的S7协议"); connected = await ConnectS7DeviceAsync(item); break; case "Modbus TCP": // Modbus TCP连接 System.Diagnostics.Debug.WriteLine("[连接] 使用设备配置的Modbus TCP协议"); connected = await ConnectModbusTcpDeviceAsync(item); break; case "Modbus TCP B+": // Modbus TCP B+连接 System.Diagnostics.Debug.WriteLine("[连接] 使用设备配置的Modbus TCP B+协议"); connected = await ConnectModbusTcpDeviceAsync(item); break; case "HTTP": // HTTP连接 System.Diagnostics.Debug.WriteLine("[连接] 使用设备配置的HTTP协议"); connected = await ConnectHttpDeviceAsync(item); break; default: System.Diagnostics.Debug.WriteLine($"[连接] 未知协议类型: {item.ProtocolType}"); break; } item.IsConnected = connected; System.Diagnostics.Debug.WriteLine($"[连接] 设备 {item.Name} 连接结果: {(connected ? "成功" : "失败")}"); System.Diagnostics.Debug.WriteLine($"[连接] ========== 连接尝试结束 =========="); } } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"[连接] 设备 {item.Name} 连接异常: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"[连接] 异常堆栈: {ex.StackTrace}"); item.IsConnected = false; } } /// /// S7协议设备连接 /// private async Task ConnectS7DeviceAsync(ChamberMonitorItem item) { try { System.Diagnostics.Debug.WriteLine($"[ConnectS7DeviceAsync] 开始配置设备: IP={ConfigIpAddress}, CPU={ConfigCpuType}, Rack={ConfigRack}, Slot={ConfigSlot}"); _thc1100.ConfigureDevice(ConfigIpAddress, ConfigCpuType, ConfigRack, ConfigSlot); bool result = await _thc1100.ConnectAsync(); System.Diagnostics.Debug.WriteLine($"[ConnectS7DeviceAsync] 连接结果: {result}, IsConnected属性值: {_thc1100.IsConnected}"); if (result) { System.Diagnostics.Debug.WriteLine("[ConnectS7DeviceAsync] 连接成功,启动定时刷新"); StartPeriodicRefresh(); } return result; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[ConnectS7DeviceAsync] 异常: {ex.Message}, 堆栈: {ex.StackTrace}"); return false; } } /// /// Modbus TCP设备连接 /// private async Task ConnectModbusTcpDeviceAsync(ChamberMonitorItem item) { try { // 配置UMC1300设备 _umc1300.ConfigureDevice(ConfigIpAddress, ConfigPort, ConfigSendTimeout, ConfigReceiveTimeout); bool result = await _umc1300.ConnectAsync(); if (result) { // 启动数据刷新 StartPeriodicRefresh(); } System.Diagnostics.Debug.WriteLine($"UMC1300 Modbus TCP连接: {ConfigIpAddress}:{ConfigPort}, 结果: {result}"); return result; } catch (System.Exception ex) { System.Diagnostics.Debug.WriteLine($"UMC1300连接异常: {ex.Message}"); return false; } } /// /// Modbus RTU设备连接 /// private async Task ConnectModbusRtuDeviceAsync(ChamberMonitorItem item) { // 实现Modbus RTU连接逻辑 System.Diagnostics.Debug.WriteLine($"Modbus RTU连接: {ConfigSerialPort}, 波特率:{ConfigBaudRate}"); await Task.Delay(500); return true; } /// /// TCP设备连接 /// private async Task ConnectTcpDeviceAsync(ChamberMonitorItem item) { // 实现TCP连接逻辑 System.Diagnostics.Debug.WriteLine($"TCP连接: {ConfigIpAddress}:{ConfigPort}"); await Task.Delay(500); return true; } /// /// HTTP设备连接 /// private async Task ConnectHttpDeviceAsync(ChamberMonitorItem item) { // 实现HTTP连接逻辑 System.Diagnostics.Debug.WriteLine($"HTTP连接: {ConfigIpAddress}:{ConfigPort}"); await Task.Delay(500); return true; } #endregion #region 生命周期管理 /// /// 导航离开时清理资源 /// public override void OnNavigatedFrom(NavigationContext navigationContext) { base.OnNavigatedFrom(navigationContext); ExecuteDisconnect(); _isInitialized = false; } #endregion } /// /// 环境箱 UI 状态及温湿度数据绑定模型 /// public class ChamberMonitorItem : BindableBase { private double _temperature; private double _humidity; private bool _isConnected; public int Id { get; set; } public string Name { get; set; } = string.Empty; public string ProtocolType { get; set; } = string.Empty; /// /// 温度(支持通知刷新) /// public double Temperature { get => _temperature; set => SetProperty(ref _temperature, value); } /// /// 湿度(支持通知刷新) /// public double Humidity { get => _humidity; set => SetProperty(ref _humidity, value); } /// /// 连接状态:True-已连接(绿灯),False-断开(红灯) /// public bool IsConnected { get => _isConnected; set { if (SetProperty(ref _isConnected, value)) { RaisePropertyChanged(nameof(ConnectButtonText)); } } } /// /// 连接按钮文本 /// public string ConnectButtonText => IsConnected ? "断开连接" : "连接设备"; } }