diff --git a/SunlightCentralizedControlManagement_SCCM_.csproj b/SunlightCentralizedControlManagement_SCCM_.csproj index 8a818e7..bde8f8a 100644 --- a/SunlightCentralizedControlManagement_SCCM_.csproj +++ b/SunlightCentralizedControlManagement_SCCM_.csproj @@ -119,6 +119,7 @@ Login.xaml + @@ -133,6 +134,7 @@ + diff --git a/UserClass/AsyncSerialPortClient.cs b/UserClass/AsyncSerialPortClient.cs new file mode 100644 index 0000000..fa478c0 --- /dev/null +++ b/UserClass/AsyncSerialPortClient.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.SerialPorts; +using TouchSocket.Sockets; + +namespace SunlightCentralizedControlManagement_SCCM_.UserClass +{ + public class AsyncSerialPortClient + { + public static async Task PortClient(SerialPortClient portclient, string com, int BAUD) + { + //var client = new SerialPortClient(); + portclient.Connecting = (client, e) => { return EasyTask.CompletedTask; };//即将连接到端口 + portclient.Connected = (client, e) => { return EasyTask.CompletedTask; };//成功连接到端口 + portclient.Closing = (client, e) => { return EasyTask.CompletedTask; };//即将从端口断开连接。此处仅主动断开才有效。 + portclient.Closed = (client, e) => { return EasyTask.CompletedTask; };//从端口断开连接,当连接不成功时不会触发。 + portclient.Received = async (c, e) => + { + + await Console.Out.WriteLineAsync(e.ByteBlock.Span.ToString(Encoding.UTF8)); + }; + + await portclient.SetupAsync(new TouchSocketConfig() + .SetSerialPortOption(new SerialPortOption() + { + BaudRate = BAUD,//波特率 + DataBits = 8,//数据位 + Parity = System.IO.Ports.Parity.None,//校验位 + PortName = com,//COM + StopBits = System.IO.Ports.StopBits.One,//停止位 + }) + .SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter() { CacheTimeout = TimeSpan.FromMilliseconds(100) }) + .ConfigurePlugins(a => + { + //a.Add(); + })); + + await portclient.ConnectAsync(); + } + } +} diff --git a/UserClass/RS485MasterStation.cs b/UserClass/RS485MasterStation.cs new file mode 100644 index 0000000..984dea2 --- /dev/null +++ b/UserClass/RS485MasterStation.cs @@ -0,0 +1,617 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.IO.Ports; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using TouchSocket.Core; +using TouchSocket.SerialPorts; +using TouchSocket.Sockets; + +namespace SunlightCentralizedControlManagement_SCCM_.UserClass +{ + #region 基础数据结构 + /// + /// 485 设备地址 + /// + public struct DeviceAddress + { + public byte Value { get; } + + public DeviceAddress(byte address) + { + if (address == 0) throw new ArgumentException("设备地址不能为0(广播地址)"); + Value = address; + } + + public static implicit operator byte(DeviceAddress address) => address.Value; + public static implicit operator DeviceAddress(byte address) => new DeviceAddress(address); + + public override string ToString() => $"0x{Value:X2}"; + } + + /// + /// 485 命令帧 + /// + public class CommandFrame + { + public DeviceAddress DeviceAddress { get; set; } + public byte FunctionCode { get; set; } + public byte[] Data { get; set; } + public ushort CRC { get; set; } + + public byte[] ToBytes() + { + // 实现帧序列化逻辑,包括CRC计算 + var dataLength = Data?.Length ?? 0; + var frame = new byte[3 + dataLength + 2]; // 地址+功能码+数据+CRC + + frame[0] = DeviceAddress; + frame[1] = FunctionCode; + + if (dataLength > 0) + Array.Copy(Data, 0, frame, 2, dataLength); + + // 计算CRC (这里使用Modbus CRC算法示例) + CRC = CalculateCRC(frame, 0, frame.Length - 2); + frame[frame.Length - 2] = (byte)(CRC & 0xFF); + frame[frame.Length - 1] = (byte)(CRC >> 8); + + return frame; + } + + private ushort CalculateCRC(byte[] data, int offset, int length) + { + // 简化的CRC计算示例,实际应根据协议实现 + ushort crc = 0xFFFF; + for (int i = offset; i < offset + length; i++) + { + crc ^= data[i]; + for (int j = 0; j < 8; j++) + { + if ((crc & 0x0001) != 0) + { + crc >>= 1; + crc ^= 0xA001; + } + else + { + crc >>= 1; + } + } + } + return crc; + } + } + + /// + /// 响应帧 + /// + public class ResponseFrame + { + public DeviceAddress DeviceAddress { get; set; } + public byte FunctionCode { get; set; } + public byte[] Data { get; set; } + public ushort CRC { get; set; } + public bool IsValid { get; set; } + public string Error { get; set; } + + public static ResponseFrame FromBytes(byte[] data) + { + // 实现帧解析逻辑,包括CRC验证 + var frame = new ResponseFrame(); + + if (data.Length < 4) // 最小帧长度 + { + frame.IsValid = false; + frame.Error = "帧长度不足"; + return frame; + } + + frame.DeviceAddress = data[0]; + frame.FunctionCode = data[1]; + + // 检查CRC + ushort receivedCRC = (ushort)(data[data.Length - 1] << 8 | data[data.Length - 2]); + ushort calculatedCRC = CalculateCRC(data, 0, data.Length - 2); + + if (receivedCRC != calculatedCRC) + { + frame.IsValid = false; + frame.Error = "CRC校验失败"; + return frame; + } + + // 提取数据部分 + if (data.Length > 4) + { + frame.Data = new byte[data.Length - 4]; + Array.Copy(data, 2, frame.Data, 0, frame.Data.Length); + } + + frame.IsValid = true; + return frame; + } + + private static ushort CalculateCRC(byte[] data, int offset, int length) + { + // 与CommandFrame相同的CRC算法 + ushort crc = 0xFFFF; + for (int i = offset; i < offset + length; i++) + { + crc ^= data[i]; + for (int j = 0; j < 8; j++) + { + if ((crc & 0x0001) != 0) + { + crc >>= 1; + crc ^= 0xA001; + } + else + { + crc >>= 1; + } + } + } + return crc; + } + } + + /// + /// 通信任务 + /// + public class CommunicationTask + { + public DeviceAddress DeviceAddress { get; set; } + public CommandFrame Command { get; set; } + public TaskCompletionSource CompletionSource { get; set; } + public int TimeoutMs { get; set; } = 1000; + public int RetryCount { get; set; } = 3; + } +#endregion + + #region 异常类 + public class RS485CommunicationException : Exception + { + public DeviceAddress DeviceAddress { get; } + public byte FunctionCode { get; } + + public RS485CommunicationException(DeviceAddress address, byte functionCode, string message) + : base($"设备 {address} 功能码 0x{functionCode:X2} 通信失败: {message}") + { + DeviceAddress = address; + FunctionCode = functionCode; + } + } + + public class RS485TimeoutException : RS485CommunicationException + { + public RS485TimeoutException(DeviceAddress address, byte functionCode) + : base(address, functionCode, "响应超时") + { + } + } + + public class RS485CRCException : RS485CommunicationException + { + public RS485CRCException(DeviceAddress address, byte functionCode) + : base(address, functionCode, "CRC校验失败") + { + } + } + #endregion + + #region 主站实现 + /// + /// 485 主站实现 + /// + public class RS485MasterStation : IDisposable + { + private readonly SerialPortClient _serialPortClient; + private readonly ConcurrentDictionary _deviceStates; + private readonly ConcurrentQueue _taskQueue; + private readonly CancellationTokenSource _cancellationTokenSource; + private Task _processingTask; + private bool _isDisposed = false; + + // 响应超时时间(毫秒) + public int ResponseTimeout { get; set; } = 1000; + + // 帧间延迟(毫秒) + public int InterFrameDelay { get; set; } = 10; + + // 最大重试次数 + public int MaxRetries { get; set; } = 3; + + /// + /// 设备状态 + /// + private class DeviceState + { + public DeviceAddress Address { get; set; } + public DateTime LastCommunication { get; set; } + public bool IsOnline { get; set; } + public int TimeoutCount { get; set; } + } + + public RS485MasterStation(string portName, int baudRate = 9600) + { + _serialPortClient = new SerialPortClient(); + _deviceStates = new ConcurrentDictionary(); + _taskQueue = new ConcurrentQueue(); + _cancellationTokenSource = new CancellationTokenSource(); + + // 配置串口 + _serialPortClient.Setup(new TouchSocketConfig() + .SetSerialPortOption(new SerialPortOption() + { + PortName = portName, + BaudRate = baudRate, + DataBits = 8, + Parity = Parity.None, + StopBits = StopBits.One + })); + + // 注册数据接收事件 + _serialPortClient.Received = OnDataReceived; + } + + /// + /// 启动主站 + /// + public void Start() + { + _serialPortClient.Connect(); + _processingTask = Task.Run(ProcessQueue, _cancellationTokenSource.Token); + Console.WriteLine("485主站已启动"); + } + + /// + /// 停止主站 + /// + public void Stop() + { + _cancellationTokenSource.Cancel(); + _serialPortClient.Close(); + Console.WriteLine("485主站已停止"); + } + + /// + /// 添加设备到监控列表 + /// + public void AddDevice(DeviceAddress address) + { + _deviceStates[address] = new DeviceState + { + Address = address, + LastCommunication = DateTime.MinValue, + IsOnline = false, + TimeoutCount = 0 + }; + Console.WriteLine($"已添加设备: {address}"); + } + + /// + /// 从监控列表移除设备 + /// + public void RemoveDevice(DeviceAddress address) + { + _deviceStates.TryRemove(address, out _); + Console.WriteLine($"已移除设备: {address}"); + } + + /// + /// 发送命令到设备 + /// + public Task SendCommandAsync(DeviceAddress address, byte functionCode, byte[] data = null, int timeoutMs = 1000, int retryCount = 3) + { + var command = new CommandFrame + { + DeviceAddress = address, + FunctionCode = functionCode, + Data = data ?? new byte[0] + }; + + var task = new CommunicationTask + { + DeviceAddress = address, + Command = command, + CompletionSource = new TaskCompletionSource(), + TimeoutMs = timeoutMs, + RetryCount = retryCount + }; + + _taskQueue.Enqueue(task); + return task.CompletionSource.Task; + } + + /// + /// 读取保持寄存器 + /// + public async Task ReadHoldingRegistersAsync(DeviceAddress address, ushort startAddress, ushort numberOfRegisters) + { + var data = new byte[4]; + data[0] = (byte)(startAddress >> 8); // 起始地址高字节 + data[1] = (byte)(startAddress & 0xFF); // 起始地址低字节 + data[2] = (byte)(numberOfRegisters >> 8); // 寄存器数量高字节 + data[3] = (byte)(numberOfRegisters & 0xFF); // 寄存器数量低字节 + + var response = await SendCommandAsync(address, 0x03, data); + + if (!response.IsValid) + throw new RS485CommunicationException(address, 0x03, response.Error); + + return response.Data; + } + + /// + /// 写入单个寄存器 + /// + public async Task WriteSingleRegisterAsync(DeviceAddress address, ushort registerAddress, ushort value) + { + var data = new byte[4]; + data[0] = (byte)(registerAddress >> 8); // 寄存器地址高字节 + data[1] = (byte)(registerAddress & 0xFF); // 寄存器地址低字节 + data[2] = (byte)(value >> 8); // 值高字节 + data[3] = (byte)(value & 0xFF); // 值低字节 + + var response = await SendCommandAsync(address, 0x06, data); + + if (!response.IsValid) + throw new RS485CommunicationException(address, 0x06, response.Error); + } + + /// + /// 处理任务队列 + /// + private async Task ProcessQueue() + { + while (!_cancellationTokenSource.Token.IsCancellationRequested) + { + if (_taskQueue.TryDequeue(out var task)) + { + await ProcessTask(task); + } + else + { + // 队列为空,执行设备轮询 + await PollDevices(); + await Task.Delay(100, _cancellationTokenSource.Token); // 短暂休眠 + } + } + } + + /// + /// 处理单个通信任务 + /// + private async Task ProcessTask(CommunicationTask task) + { + int retryCount = 0; + ResponseFrame response = null; + + while (retryCount < task.RetryCount && !_cancellationTokenSource.Token.IsCancellationRequested) + { + try + { + // 发送命令 + var commandData = task.Command.ToBytes(); + _serialPortClient.Send(commandData); + + // 等待响应 + var timeoutTask = Task.Delay(task.TimeoutMs, _cancellationTokenSource.Token); + var responseTask = task.CompletionSource.Task; + + var completedTask = await Task.WhenAny(responseTask, timeoutTask); + + if (completedTask == responseTask) + { + response = await responseTask; + if (response.IsValid) + { + UpdateDeviceState(task.DeviceAddress, true); + task.CompletionSource.SetResult(response); + return; + } + else + { + throw new RS485CRCException(task.DeviceAddress, task.Command.FunctionCode); + } + } + else + { + throw new RS485TimeoutException(task.DeviceAddress, task.Command.FunctionCode); + } + } + catch (RS485CommunicationException ex) + { + retryCount++; + UpdateDeviceState(task.DeviceAddress, false); + + if (retryCount >= task.RetryCount) + { + task.CompletionSource.SetException(ex); + return; + } + + // 等待一段时间后重试 + await Task.Delay(InterFrameDelay, _cancellationTokenSource.Token); + } + } + } + + /// + /// 轮询所有设备状态 + /// + private async Task PollDevices() + { + foreach (var deviceState in _deviceStates.Values.ToList()) + { + // 检查设备是否需要轮询(例如,超过一定时间未通信) + if ((DateTime.Now - deviceState.LastCommunication).TotalSeconds > 30) + { + try + { + // 发送诊断命令(如读取设备状态) + await ReadHoldingRegistersAsync(deviceState.Address, 0, 1); + Console.WriteLine($"设备 {deviceState.Address} 轮询成功"); + } + catch (Exception ex) + { + Console.WriteLine($"设备 {deviceState.Address} 轮询失败: {ex.Message}"); + } + + // 添加帧间延迟 + await Task.Delay(InterFrameDelay, _cancellationTokenSource.Token); + } + } + } + + /// + /// 数据接收处理 + /// + private Task OnDataReceived(ISerialPortClient client, ReceivedDataEventArgs e) + { + try + { + // 解析响应帧 + var response = ResponseFrame.FromBytes(e.ByteBlock.ReadBytesPackage()); + + if (response.IsValid) + { + // 查找匹配的任务并设置结果 + foreach (var task in _taskQueue.Where(t => t.DeviceAddress.Value == response.DeviceAddress.Value)) + { + task.CompletionSource.TrySetResult(response); + } + + UpdateDeviceState(response.DeviceAddress, true); + } + else + { + Console.WriteLine($"收到无效响应: {response.Error}"); + } + } + catch (Exception ex) + { + Console.WriteLine($"处理接收数据时出错: {ex.Message}"); + } + + return Task.CompletedTask; + } + + /// + /// 更新设备状态 + /// + private void UpdateDeviceState(DeviceAddress address, bool communicationSuccess) + { + if (_deviceStates.TryGetValue(address, out var state)) + { + state.LastCommunication = DateTime.Now; + + if (communicationSuccess) + { + state.IsOnline = true; + state.TimeoutCount = 0; + } + else + { + state.TimeoutCount++; + if (state.TimeoutCount > MaxRetries) + { + state.IsOnline = false; + Console.WriteLine($"设备 {address} 已离线"); + } + } + } + } + + /// + /// 获取所有设备状态 + /// + public Dictionary GetDeviceStatuses() + { + return _deviceStates.ToDictionary( + kvp => kvp.Key, + kvp => kvp.Value.IsOnline); + } + + /// + /// 资源释放 + /// + public void Dispose() + { + if (!_isDisposed) + { + _isDisposed = true; + _cancellationTokenSource.Cancel(); + _serialPortClient.SafeDispose(); + _cancellationTokenSource.Dispose(); + } + } + } + #endregion + + #region 使用示例 + class Program + { + static async Task Main(string[] args) + { + // 创建485主站实例 + using (var master = new RS485MasterStation("COM1", 9600)) + + try + { + // 添加要监控的设备 + master.AddDevice(0x01); + master.AddDevice(0x02); + master.AddDevice(0x03); + + // 启动主站 + master.Start(); + + // 等待一段时间让主站初始化 + await Task.Delay(1000); + + // 示例1: 读取设备1的保持寄存器 + try + { + var data = await master.ReadHoldingRegistersAsync(0x01, 0, 10); + Console.WriteLine($"成功读取设备1的寄存器数据: {BitConverter.ToString(data)}"); + } + catch (RS485CommunicationException ex) + { + Console.WriteLine(ex.Message); + } + + // 示例2: 向设备2写入寄存器值 + try + { + await master.WriteSingleRegisterAsync(0x02, 0x1000, 0x1234); + Console.WriteLine("成功向设备2写入寄存器值"); + } + catch (RS485CommunicationException ex) + { + Console.WriteLine(ex.Message); + } + + // 显示所有设备状态 + var statuses = master.GetDeviceStatuses(); + foreach (var status in statuses) + { + Console.WriteLine($"设备 {status.Key}: {(status.Value ? "在线" : "离线")}"); + } + + // 保持运行 + Console.WriteLine("按任意键退出..."); + Console.ReadKey(); + } + finally + { + master.Stop(); + } + } + } + #endregion +} diff --git a/ViewModel/MainWindowViewModel.cs b/ViewModel/MainWindowViewModel.cs index 22a8c31..130fb76 100644 --- a/ViewModel/MainWindowViewModel.cs +++ b/ViewModel/MainWindowViewModel.cs @@ -32,10 +32,11 @@ using System.Windows.Media; using System.Windows.Threading; using System.Xml.Linq; using TouchSocket.Core; -using TouchSocket.Sockets; using TouchSocket.SerialPorts; +using TouchSocket.Sockets; using static MaterialDesignThemes.Wpf.Theme; using static SunlightCentralizedControlManagement_SCCM_.UserClass.SqliteHelper; +using static SunlightCentralizedControlManagement_SCCM_.View.MachinesView; using static SunlightCentralizedControlManagement_SCCM_.ViewModel.ManualDyelotModel; using static System.Net.WebRequestMethods; using static System.Windows.Forms.AxHost; @@ -120,6 +121,8 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel UPort();//启动串口 CountDown(); TcpClientNEW(); + PortClientNEW(); + ClientNEW(); SQL_LINK(); } public static void USERCapacity(string user) //权限 @@ -361,7 +364,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel "AND EndTime >'" + DateTime.Now.AddHours(-8).ToString("yyyy/MM/dd HH:mm:ss") + "'", null).Tables[0]; //读取表写入缓存 for (int k = 0; k < WorkOrderstepdata.Rows.Count; k++) { - if (Selet_Machines(Machines, "Type", "ID='" + k + "'").ToString() == "838") + if (Convert.ToBoolean(Selet_Machines(Machines, "Type", "ID='" + k + "'"))) { string WorkOrderdata_m = WorkOrderstepdata.Select()[k].Field("Machines").ToString(); DataTable dataTable = WorkOrderSQL.ExecuteDataSet("select * from WorkorderSteps where WorkOrder='" + @@ -375,7 +378,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel WorkOrderSQL.Update("WorkOrder", new Dictionary { { "State", 112 } }, "WorkOrder ='" + WorkOrderstepdata.Select()[k].Field("WorkOrder").ToString() + "'", null); } - else if (Selet_Machines(Machines, "Type", "ID='" + k + "'").ToString() == "828") + else { } @@ -385,7 +388,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel "AND EndTime >'" + DateTime.Now.AddHours(-8).ToString("yyyy/MM/dd HH:mm:ss") + "'", null).Tables[0]; //读取表写入缓存 for (int k = 0; k < WorkOrderdata.Rows.Count; k++) { - if (Selet_Machines(Machines, "Type", "ID='" + k + "'").ToString() == "838") + if (Convert.ToBoolean( Selet_Machines(Machines, "Type", "ID='" + k + "'"))) { string WorkOrderdata_m = WorkOrderdata.Select()[k].Field("Machines").ToString(); string State = Selet_Machines(Machines, "State", "Name='" + WorkOrderdata_m + "'").ToString(); @@ -410,7 +413,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel "WorkOrder ='" + WorkOrderdata.Select()[k].Field("WorkOrder").ToString() + "'", null); } } - else if (Selet_Machines(Machines, "Type", "ID='" + k + "'").ToString() == "828") + else { string WorkOrderdata_m = WorkOrderdata.Select()[k].Field("Machines").ToString(); string State = Selet_Machines(Machines, "State", "Name='" + WorkOrderdata_m + "'").ToString(); @@ -442,7 +445,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel "AND EndTime >'" + DateTime.Now.AddHours(-8).ToString("yyyy/MM/dd HH:mm:ss") + "'", null).Tables[0]; //读取表写入缓存 for (int k = 0; k < WorkOrderset_.Rows.Count; k++) { - if (Selet_Machines(Machines, "Type", "ID='" + k + "'").ToString() == "838") + if (Convert.ToBoolean(Selet_Machines(Machines, "Type", "ID='" + k + "'"))) { string WorkOrderset_m = WorkOrderset_.Select()[k].Field("Machines").ToString(); string WorkOrderset_w = WorkOrderset_.Select()[k].Field("WorkOrder").ToString(); @@ -462,7 +465,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel WorkOrderSQL.Update("WorkOrder", new Dictionary { { "State", 110 } }, "WorkOrder ='" + WorkOrderdata.Select()[k].Field("WorkOrder").ToString() + "'", null); } - else if (Selet_Machines(Machines, "Type", "ID='" + k + "'").ToString() == "828") + else { string WorkOrderset_m = WorkOrderset_.Select()[k].Field("Machines").ToString(); string WorkOrderset_w = WorkOrderset_.Select()[k].Field("WorkOrder").ToString(); @@ -489,27 +492,27 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel //系统时间 Sys_Time = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); - //更新机台状态与发送指令 - for (int i = 0; i < Machinesdata_Count; i++) - { - if (Selet_Machines(Machines, "Type", "ID='" + i + "'").ToString() == "838") + //更新机台状态与发送指令 + foreach (DataRow MachinesRow in Machines.Rows) + { + if (Convert.ToBoolean(MachinesRow["Type"])) { - if (Selet_Machines(Machines, "State", "ID='" + i + "'").ToString() == "802") + if (MachinesRow["State"].ToString() == "802") { stringQueue.Enqueue(new QueueString { - ID = i, - DAT = "SC830" + Selet_Machines(Machines, "SYSKEY", "ID='" + i + "'").ToString() + ID = Convert.ToInt16( MachinesRow["ID"]), + DAT = "SC830" + MachinesRow["SYSKEY"] });//信息插入队列 - bool mode = Machines.Select("ID='" + i + "'").First().Field("LOCK");//发送锁定状态 + bool mode =Convert.ToBoolean( MachinesRow["LOCK"]) ;//发送锁定状态 if (mode) { Dictionary dat_829 = new Dictionary(); dat_829.Clear(); dat_829.Add("NAME", "LOCK"); dat_829.Add("VALUE", "True"); - DataRow drEmployee = Machines.Select("ID='" + i + "'").First(); + DataRow drEmployee = Machines.Select("ID='" + MachinesRow["ID"] + "'").First(); int index = Convert.ToInt16(drEmployee.Field("ID")); stringQueue.Enqueue(new QueueString { @@ -518,98 +521,93 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel }); } - Updata_Machines(Machines, "State", "ID='" + i + "'", "101"); + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "101"); } - int m_run = (int)Selet_Machines(Machines, "WORK_RUN", "ID='" + i + "'"); + int m_run =Convert.ToInt16( MachinesRow["WORK_RUN"]); if (m_run == 0) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "101");//停止状态 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "101");//停止状态 } else if (m_run == 1) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "101");//暂停状态 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "101");//暂停状态 } else if (m_run == 2) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "202");//运行 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "202");//运行 } - if ((bool)Selet_Machines(Machines, "ERR", "ID='" + i + "'")) + if (Convert.ToBoolean(MachinesRow["ERR"])) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "309");//错误 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "309");//错误 } - string mac_s = Selet_Machines(Machines, "State", "ID='" + i + "'").ToString(); + string mac_s = MachinesRow["State"].ToString(); if ((mac_s == "101") || (mac_s == "201") || (mac_s == "202") || (mac_s == "301") || (mac_s == "309"))//获取信息 { stringQueueinf.Enqueue(new QueueString { - ID = i, - DAT = "SC830" + Selet_Machines(Machines, "SYSKEY", "ID='" + i + "'").ToString() + ID = Convert.ToInt16( MachinesRow["ID"]), + DAT = "SC830" + MachinesRow["SYSKEY"] });//信息插入队列 } } - else if (Selet_Machines(Machines, "Type", "ID='" + i + "'").ToString() == "828") + else { - if (Selet_Machines(Machines, "State", "ID='" + i + "'").ToString() == "800") + if (MachinesRow["State"].ToString() == "800") {//串口发送 - string POR = Selet_Machines(Machines, "Serial", "ID='" + i + "'").ToString(); + string POR = MachinesRow["Serial"].ToString(); stringQueueSerial.Enqueue(new QueueSerial { ID = POR, - DAT = "SC830[" + - Selet_Machines(Machines, "Station", "ID='" + i + "'") + "]" + DAT = "SC830[" + MachinesRow["Station"] + "]" }); - bool mode = Machines.Select("ID='" + i + "'").First().Field("LOCK");//发送锁定状态 + bool mode =Convert.ToBoolean( MachinesRow["LOCK"]);//发送锁定状态 if (mode) { Dictionary dat_829 = new Dictionary(); dat_829.Clear(); dat_829.Add("NAME", "LOCK"); - dat_829.Add("VALUE", "True"); - DataRow drEmployee = Machines.Select("ID='" + i + "'").First(); + dat_829.Add("VALUE", "True"); stringQueueSerial.Enqueue(new QueueSerial { ID = POR, - DAT = "SC829[" + - Selet_Machines(Machines, "Station", "ID='" + i + "'") + "]" + - dat_829.ToJsonString() + DAT = "SC829[" + MachinesRow["Station"] + "]" + dat_829.ToJsonString() }); } - Updata_Machines(Machines, "State", "ID='" + i + "'", "101"); + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "101"); } - int m_run = (int)Selet_Machines(Machines, "WORK_RUN", "ID='" + i + "'"); + int m_run =Convert.ToInt16( MachinesRow["WORK_RUN"]); if (m_run == 0) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "101");//停止状态 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "101");//停止状态 } else if (m_run == 1) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "101");//暂停状态 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "101");//暂停状态 } else if (m_run == 2) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "202");//运行 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "202");//运行 } - if ((bool)Selet_Machines(Machines, "ERR", "ID='" + i + "'")) + if (Convert.ToBoolean(MachinesRow["ERR"])) { - Updata_Machines(Machines, "State", "ID='" + i + "'", "309");//错误 + Updata_Machines(Machines, "State", "ID='" + MachinesRow["ID"] + "'", "309");//错误 } - string mac_s = Selet_Machines(Machines, "State", "ID='" + i + "'").ToString(); + string mac_s = MachinesRow["State"].ToString(); if ((mac_s == "101") || (mac_s == "201") || (mac_s == "202") || (mac_s == "301") || (mac_s == "309"))//获取信息 { - string POR = Selet_Machines(Machines, "Serial", "ID='" + i + "'").ToString(); + string POR = MachinesRow["Serial"].ToString(); stringQueueSerial.Enqueue(new QueueSerial { ID = POR, - DAT = "SC830[" + - Selet_Machines(Machines, "Station", "ID='" + i + "'") + "]" + DAT = "SC830[" + MachinesRow["Station"] + "]" }); } } @@ -630,66 +628,65 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel } async void Tick_Event_5S()//Tick_Event周期执行事件5S { - for (int i = 0; i < Machinesdata_Count; i++) - {/**发送800指令**/ - if (Selet_Machines(Machines, "State", "ID='" + i + "'").ToString() == "801") + foreach (DataRow MachinesRow in Machines.Rows) + { + /**发送800指令**/ + if (MachinesRow["State"].ToString() == "801") { stringQueue.Enqueue(new QueueString { - ID = i, - DAT = "SC800:SCCM[" + Selet_Machines(Machines, "IP", "ID='" + i + "'") + ";" + - Selet_Machines(Machines, "Prot", "ID='" + i + "'") + "]" + ID = Convert.ToInt16(MachinesRow["ID"]), + DAT = "SC800:SCCM[" + MachinesRow["IP"] + ";" + MachinesRow["Prot"] + "]" });//信息插入队列 } /**染机用户信息**/ try { - if ((int)Selet_Machines(Machines, "UserInfoStart", "ID='" + i + "'") == 901)//打开用户提示信息 + if (MachinesRow["UserInfoStart"].ToString() == "901")//打开用户提示信息 { MainWindow.InfData.Rows.Add(new object[] { - Selet_Machines(Machines, "Name", "ID='" + i + "'"), - Properties.Resources.Pequest + Selet_Machines(Machines, "UserInfo", "ID='" + i + "'"), - Selet_Machines(Machines, "SYSKEY", "ID='" + i + "'"), - Selet_Machines(Machines, "ID", "ID='" + i + "'")}); - Updata_Machines(Machines, "UserInfoStart", "ID='" + i + "'", "900"); + MachinesRow["Name"],Properties.Resources.Pequest + MachinesRow["UserInfo"], + MachinesRow["SYSKEY"],MachinesRow["ID"]}); + + Updata_Machines(Machines, "UserInfoStart", "ID='" + MachinesRow["ID"] + "'", "900"); } - if (Selet_Machines(Machines, "UserInfoStart", "ID='" + i + "'").ToString() == "902")//删除用户提示信息 + if (MachinesRow["UserInfoStart"].ToString() == "902")//删除用户提示信息 { - MainWindow.InfData.Select("ID='" + i + "'").First().Delete(); + MainWindow.InfData.Select("ID='" + MachinesRow["ID"] + "'").First().Delete(); } } catch (Exception EX) { LogGing.ERRDATA(EX); } /**染机呼叫状态**/ try { - if ((bool)Selet_Machines(Machines, "CALL", "ID='" + i + "'")) + if (Convert.ToBoolean(MachinesRow["CALL"])) { - if (Selet_Machines(Machines, "Type", "ID='" + i + "'").ToString() == "828") + if (Convert.ToBoolean(MachinesRow["Type"])) { - string POR = Selet_Machines(Machines, "Serial", "ID='" + i + "'").ToString(); - - stringQueueSerial.Enqueue(new QueueSerial + stringQueue.Enqueue(new QueueString { - ID = POR, - DAT = "SC827[" + - Selet_Machines(Machines, "Station", "ID='" + i + "'") + "]" + ID = Convert.ToInt16(MachinesRow["ID"]), + DAT = "SC827" + MachinesRow["SYSKEY"] }); } - else if (Selet_Machines(Machines, "Type", "ID='" + i + "'").ToString() == "838") + else { - stringQueue.Enqueue(new QueueString + string POR = MachinesRow["Serial"].ToString(); + + stringQueueSerial.Enqueue(new QueueSerial { - ID = i, - DAT = "SC827" + Selet_Machines(Machines, "SYSKEY", "ID='" + i + "'") + ID = POR, + DAT = "SC827[" + MachinesRow["Station"] }); + } } } catch (Exception EX) { LogGing.ERRDATA(EX); } try {//处理呼叫请求列表完成发送后(202》203) - if (Dyelot_CALL.Select("State='202'").Count() > 0) + if (Dyelot_CALL.Select("State='202'").Count() > 0) { DataRow row = Dyelot_CALL.Select("State='202'").First(); var r = await bDCSqlHelper.UPDATA("Machines", "Name = '" + row.Field("Machine") + "'", row); @@ -719,10 +716,10 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel catch (Exception EX) { LogGing.ERRDATA(EX); } try {//检查呼叫回复列表确认是否完成(203=>301) - if (Dyelot_CALL.Select("State='203'").Count() > 0) + if (Dyelot_CALL.Select("State='203'").Count() > 0) { DataTable dt = new DataTable(); - // DataRow[] dataRows = Dyelot_CALL.Select("State='203'"); + // DataRow[] dataRows = Dyelot_CALL.Select("State='203'"); foreach (DataRow dataRow in Dyelot_CALL.Select("State='203'")) { if ((dataRow["State"].ToString() != "301") && (dataRow["State"].ToString() != "309")) @@ -736,15 +733,15 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel { if (dt.Select("DyeState = 301").Count() > 0) { - // Dyelot_CALL.Rows.Remove(dataRow); + // Dyelot_CALL.Rows.Remove(dataRow); DataTable dr = await bDCSqlHelper.SELECT("DyelotsBulkedRecipe", "Dyelot = '" + dataRow.Field("Dyelot") + "' AND ReDye = " + dataRow.Field("ReDye") + " AND StepNumber = " + dataRow.Field("Step")); - foreach (DataRow Row in Dyelot_CALL.Select("Dyelot='"+ dataRow["Dyelot"]+ "' and Redye ='"+ - dataRow["Redye"]+ "' AND Step = '"+ dataRow["Step"] + "'")) + foreach (DataRow Row in Dyelot_CALL.Select("Dyelot='" + dataRow["Dyelot"] + "' and Redye ='" + + dataRow["Redye"] + "' AND Step = '" + dataRow["Step"] + "'")) { if (dr.Rows.Count > 0) { @@ -766,7 +763,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel } } } - else if(dt.Select("DyeState = 309").Count() > 0) + else if (dt.Select("DyeState = 309").Count() > 0) { foreach (DataRow Row in Dyelot_CALL.Select("Dyelot='" + dataRow["Dyelot"] + "' and Redye ='" + dataRow["Redye"] + "' AND Step = '" + dataRow["Step"] + "'")) @@ -795,7 +792,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel { if (dt.Select("PowderState = 301").Count() > 0) { - // Dyelot_CALL.Rows.Remove(dataRow); + // Dyelot_CALL.Rows.Remove(dataRow); DataTable dr = await bDCSqlHelper.SELECT("DyelotsBulkedRecipe", "Dyelot = '" + dataRow.Field("Dyelot") + "' AND ReDye = " + dataRow.Field("ReDye") + @@ -846,7 +843,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel { if (dt.Select("ChemicalState = 301").Count() > 0) { - // Dyelot_CALL.Rows.Remove(dataRow); + // Dyelot_CALL.Rows.Remove(dataRow); DataTable dr = await bDCSqlHelper.SELECT("DyelotsBulkedRecipe", "Dyelot = '" + dataRow.Field("Dyelot") + "' AND ReDye = " + dataRow.Field("ReDye") + @@ -865,7 +862,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel Row["DispenseEndTime"] = data.Field("DispenseEndTime").ToString("yyyy/MM/dd HH:mm:ss"); Row.EndEdit(); } - else + else { Row.BeginEdit(); Row["State"] = 301; @@ -898,7 +895,7 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel try {//301列表发送完成至染机(203=>301) foreach (DataRow row in Dyelot_CALL.Select("State='301' OR State='309'")) - { + { Dictionary Product_ = new Dictionary();//缓存函数 Product_.Add("State", row.Field("State")); Product_.Add("Step", row.Field("Step")); @@ -915,10 +912,10 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel "SYSKEY", "Name='" + row.Field("Machine") + "'") + Product_.ToJsonString() }); if (row["State"].ToString() == "309") - { - MainWindow.InfData.Rows.Add(new object[] { row["Machine"], - Resources.Step + row["Step"]+ Resources.DispenseException, - Selet_Machines(Machines, "SYSKEY", "Name='" + row["Machine"] + "'"), + { + MainWindow.InfData.Rows.Add(new object[] { row["Machine"], + Resources.Step + row["Step"]+ Resources.DispenseException, + Selet_Machines(Machines, "SYSKEY", "Name='" + row["Machine"] + "'"), Selet_Machines(Machines, "ID", "Name='" + row["Machine"] + "'")}); } Dyelot_CALL.Rows.Remove(row); @@ -927,11 +924,13 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel catch (Exception EX) { LogGing.ERRDATA(EX); } + } } void Tick_Event_30S() { - for (int i = 0; i < Machines.Rows.Count; i++) + /*曲线图*/ + for (int i = 0; i < Machines.Rows.Count; i++)//曲线图 { if (Selet_Machines(Machines, "State", "ID='" + i + "'").ToString() !="800") { @@ -946,14 +945,9 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel public static TcpClient[] MachiensTcpClient = new TcpClient[999]; public static DataRow[] machinesdata = new DataRow[999]; - public int Machinesdata_Count; - public void TcpClientNEW() + public void ClientNEW() { - // bool Machine_ ; - machinesdata = Machines.Select("PORT>0 AND IP<>''", "id asc");//获取连接有效的组 - Machinesdata_Count = machinesdata.Count(); - - foreach (DataRow dataRow in Machines.Rows) + foreach (DataRow dataRow in Machines.Rows) { dataRow.BeginEdit(); dataRow["State"] = 800; @@ -967,10 +961,30 @@ namespace SunlightCentralizedControlManagement_SCCM_.ViewModel dataRow["UserInfoStart"] = 900; dataRow.EndEdit(); dataRow.AcceptChanges(); - - MachiensTcpClient[Convert.ToInt16(dataRow["ID"])]= new TcpClient(); - _ = AsyncTcpClient.TcpClient(MachiensTcpClient[Convert.ToInt16(dataRow["ID"])] //建立tcp连接 - , dataRow["IP"].ToString(), dataRow["PORT"].ToString()); + } + } + public void TcpClientNEW() + { + foreach (DataRow dataRow in Machines.Rows) + { + if (Convert.ToBoolean(dataRow["Type"])) + { + MachiensTcpClient[Convert.ToInt16(dataRow["ID"])] = new TcpClient(); + _ = AsyncTcpClient.TcpClient(MachiensTcpClient[Convert.ToInt16(dataRow["ID"])] //建立tcp连接 + , dataRow["IP"].ToString(), dataRow["PORT"].ToString()); + } + } + } + public void PortClientNEW() + { + foreach (DataRow dataRow in Machines.Rows) + { + if (!Convert.ToBoolean(dataRow["Type"])) + { + // MachiensTcpClient[Convert.ToInt16(dataRow["ID"])] = new TcpClient(); + // _ = AsyncTcpClient.TcpClient(MachiensTcpClient[Convert.ToInt16(dataRow["ID"])] //建立tcp连接 + // , dataRow["IP"].ToString(), dataRow["PORT"].ToString()); + } } }