using BDU.Models; using BDU.Tools; using BDU.Windows; using DeviceCommand.Base; using DocumentFormat.OpenXml.Drawing.Charts; using Newtonsoft.Json; using Org.BouncyCastle.Utilities; using System.Collections.ObjectModel; using System.IO.Ports; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using TSMasterCAN; namespace BDU.Logic { public static class DeviceConnect { private static ParameterModel devicePara = new(); public static async Task InitAndConnectDevice(ProgramModel program, DeviceModel device, bool isDeviceAdd = false) { try { devicePara = new() { Name = device.Name, IsVisible = false }; if (isDeviceAdd) { device.ParameterID = devicePara.ID; program.Devices.Add(device); } else { devicePara.ID = device.ParameterID; } program.Parameters.Add(devicePara); switch (device.Type) { case "Tcp": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(Tcp); Tcp tcp = new(); var DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; tcp.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); device.CommunicationProtocol = tcp; var tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); var tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = tcp; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "Udp": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(Udp); Udp udp = new(); DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; udp.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); device.CommunicationProtocol = udp; tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = udp; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "ModbusTcp": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(ModbusTcp); ModbusTcp modbusTcp = new(); DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; modbusTcp.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); device.CommunicationProtocol = modbusTcp; tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = modbusTcp; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "CAN": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(CAN); tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); if (tmpDevice != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; CAN.DisConnect(); var re1 = CAN.Init("ATS测试系统"); var re2 = CAN.LoadDBC(SystemConfig.Instance.DBCFilePath, [0, 1, 2, 3], out _); var re3 = CAN.Connect(); if (re1 == 0 && re2 == 0 && re3 == 0) { tmpDevice.Connected = true; } else { tmpDevice.Connected = false; } _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "串口": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(Serial_Port); // 串口设备初始化 Serial_Port serialPort = new (); DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; StopBits stopBitsEnum = GetstopBitsEnum(DeviceConnectSettings[3].Value); Parity parityEnum = GetparityEnum(DeviceConnectSettings[4].Value); serialPort.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value) , Convert.ToInt32(DeviceConnectSettings[2].Value), stopBitsEnum, parityEnum , Convert.ToInt32(DeviceConnectSettings[5].Value), Convert.ToInt32(DeviceConnectSettings[6].Value)); // 将串口通信协议赋值给设备 device.CommunicationProtocol = serialPort; // 更新设备和参数 tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = serialPort; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "ModbusRtu_Tcp": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(ModbusRtu_Tcp); ModbusRtu_Tcp modbusRtu = new(); DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; modbusRtu.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); device.CommunicationProtocol = modbusRtu; tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = modbusRtu; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "ModbusRtu_Udp": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(ModbusRtu_Udp); ModbusRtu_Udp modbusRtuUdp = new(); DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; modbusRtuUdp.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value)); device.CommunicationProtocol = modbusRtuUdp; tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = modbusRtuUdp; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; case "ModbusRtu_Serial": program.Parameters.First(x => x.ID == device.ParameterID).Type = typeof(ModbusRtu_Udp); ModbusRtu_Serial modbusRtu_Serial = new(); DeviceConnectSettings = JsonConvert.DeserializeObject>(device.ConnectString)!; stopBitsEnum = GetstopBitsEnum(DeviceConnectSettings[3].Value); parityEnum = GetparityEnum(DeviceConnectSettings[4].Value); modbusRtu_Serial.CreateDevice(DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value) , Convert.ToInt32(DeviceConnectSettings[2].Value), stopBitsEnum, parityEnum , Convert.ToInt32(DeviceConnectSettings[5].Value), Convert.ToInt32(DeviceConnectSettings[6].Value)); device.CommunicationProtocol = modbusRtu_Serial; tmpDevice = program.Devices.FirstOrDefault(x => x.ID == device.ID); tmpParameter = program.Parameters.FirstOrDefault(x => x.ID == device.ParameterID); if (tmpDevice != null && tmpParameter != null) { tmpDevice.CommunicationProtocol = device.CommunicationProtocol; tmpParameter.Value = modbusRtu_Serial; _ = DeviceConnectedStatusWatchTask(tmpDevice.ID); } break; } } catch (Exception ex) { Log.Error($"设备 [ {device.Name} ] 初始化连接失败:{ex.Message}"); } } private static async Task DeviceConnectedStatusWatchTask(Guid deviceID) { DeviceModel? watchedDevice = MainWindow.Instance.Program.Devices.FirstOrDefault(x => x.ID == deviceID); while (watchedDevice != null) { try { switch (watchedDevice.Type) { case "Tcp": Tcp tcp = (Tcp)watchedDevice.CommunicationProtocol!; var DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; Tcp.ChangeDeviceConfig(tcp, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); var re = await Tcp.ConnectAsync(tcp); await Tcp.SendAsync(tcp, ""); if (re && tcp.TcpClient.Connected) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "Udp": Udp udp = (Udp)watchedDevice.CommunicationProtocol!; DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; Udp.ChangeDeviceConfig(udp, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); re = await Udp.ConnectAsync(udp); await Udp.SendAsync(udp, Encoding.UTF8.GetBytes("")); if (re && udp.UdpClient.Client.Connected) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "ModbusTcp": ModbusTcp modbusTcp = (ModbusTcp)watchedDevice.CommunicationProtocol!; DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; ModbusTcp.ChangeDeviceConfig(modbusTcp, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); re = await ModbusTcp.ConnectAsync(modbusTcp); await modbusTcp.TcpClient.Client.SendAsync(Encoding.UTF8.GetBytes("")); if (re && modbusTcp.TcpClient.Connected) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "CAN": var re1 = CAN.Init("ATS测试系统"); //var re2 = CAN.LoadDBC(SystemConfig.Instance.DBCFilePath, [0, 1, 2, 3], out _); //var re3 = CAN.Connect(); if (re1 == 0 && CAN.ConnectFlag) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "串口": Serial_Port serialPort = (Serial_Port)watchedDevice.CommunicationProtocol!; DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; StopBits stopBitsEnum = GetstopBitsEnum(DeviceConnectSettings[3].Value); Parity parityEnum = GetparityEnum(DeviceConnectSettings[4].Value); Serial_Port.ChangeDeviceConfig(serialPort, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value) , Convert.ToInt32(DeviceConnectSettings[2].Value), stopBitsEnum, parityEnum , Convert.ToInt32(DeviceConnectSettings[5].Value), Convert.ToInt32(DeviceConnectSettings[6].Value)); re = await Serial_Port.ConnectAsync(serialPort); await Serial_Port.SendAsync(serialPort, ""); if (re) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "ModbusRtu_Tcp": ModbusRtu_Tcp modbusRtu = (ModbusRtu_Tcp)watchedDevice.CommunicationProtocol!; DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; stopBitsEnum = GetstopBitsEnum(DeviceConnectSettings[3].Value); //parityEnum = GetparityEnum(DeviceConnectSettings[4].Value); ModbusRtu_Tcp.ChangeDeviceConfig(modbusRtu, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value), Convert.ToInt32(DeviceConnectSettings[2].Value), Convert.ToInt32(DeviceConnectSettings[3].Value)); re = await ModbusRtu_Tcp.ConnectAsync(modbusRtu); await modbusRtu.TcpClient.Client.SendAsync(Encoding.UTF8.GetBytes("")); if (re && modbusRtu.TcpClient.Connected) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "ModbusRtu_Udp": ModbusRtu_Udp modbusRtuUdp = (ModbusRtu_Udp)watchedDevice.CommunicationProtocol!; DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; //stopBitsEnum = GetstopBitsEnum(DeviceConnectSettings[3].Value); //parityEnum = GetparityEnum(DeviceConnectSettings[4].Value); ModbusRtu_Udp.ChangeDeviceConfig(modbusRtuUdp, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value) , Convert.ToInt32(DeviceConnectSettings[2].Value)); CancellationToken ct = default; re = await modbusRtuUdp.ConnectAsync(ct); if (re) { await modbusRtuUdp.SendRequestAndReceiveAsync(Encoding.UTF8.GetBytes(""), CancellationToken.None); watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; case "ModbusRtu_Serial": ModbusRtu_Serial modbusRtu_Serial = (ModbusRtu_Serial)watchedDevice.CommunicationProtocol!; DeviceConnectSettings = JsonConvert.DeserializeObject>(watchedDevice.ConnectString)!; stopBitsEnum = GetstopBitsEnum(DeviceConnectSettings[3].Value); parityEnum = GetparityEnum(DeviceConnectSettings[4].Value); ModbusRtu_Serial.ChangeDeviceConfig(modbusRtu_Serial, DeviceConnectSettings[0].Value, Convert.ToInt32(DeviceConnectSettings[1].Value) , Convert.ToInt32(DeviceConnectSettings[2].Value), stopBitsEnum, parityEnum , Convert.ToInt32(DeviceConnectSettings[5].Value), Convert.ToInt32(DeviceConnectSettings[6].Value)); CancellationToken ctSerial = default; re = await ModbusRtu_Serial.ConnectAsync(modbusRtu_Serial, ctSerial); if (re) { watchedDevice.Connected = true; } else { watchedDevice.Connected = false; } break; } } catch (Exception ex) { watchedDevice.Connected = false; watchedDevice.ErrorMessage = ex.Message; } finally { await Task.Delay(1000); if (watchedDevice.Connected && !string.IsNullOrEmpty(watchedDevice.ErrorMessage)) { watchedDevice.ErrorMessage = ""; } watchedDevice = MainWindow.Instance.Program.Devices.FirstOrDefault(x => x.ID == deviceID); } } } private static StopBits GetstopBitsEnum(string Value) { StopBits stopBitsEnum; // 使用 Enum.TryParse 转换字符串到 StopBits 枚举 if (!Enum.TryParse(Value, true, out stopBitsEnum)) { throw new TimeoutException($"转换失败!无效的停止位字符串"); } return stopBitsEnum; } private static Parity GetparityEnum(string Value) { string ParityEnumValue = GetParityEnumValue(Value); Parity parityEnum; // 使用 Enum.TryParse 转换字符串到 Parity 枚举 if (!Enum.TryParse(ParityEnumValue, true, out parityEnum)) { throw new TimeoutException($"转换失败!无效的校验位字符串"); } return parityEnum; } private static string GetParityEnumValue(string Value) { return Value switch { "无" => "None", "奇" => "Odd", "偶" => "Even", _ => "", }; } } }