BDU/ATS/Logic/DeviceConnect.cs

434 lines
23 KiB
C#

using ATS.Models;
using ATS.Tools;
using ATS.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 ATS.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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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<ObservableCollection<DeviceConnectSettingModel>>(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",
_ => "",
};
}
}
}