434 lines
23 KiB
C#
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",
|
|
_ => "",
|
|
};
|
|
}
|
|
}
|
|
}
|