kazelee
2025-06-24 ad56deb081831090408f97b1c73e61a2eaed8657
整合部分Modbus和TCP Socket方式处理设备交互的逻辑
3 文件已重命名
2个文件已添加
1个文件已修改
1个文件已删除
422 ■■■■■ 已修改文件
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/140a3f27-91f0-4f76-83cb-8a8da5896f2a.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/340c6236-9991-45c1-b640-67c509d34eff.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/51f15dd6-39b1-4e8d-8d5a-7cdebd5ca9d8.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/c349b9a0-3c00-4a74-bcf5-5ba46f79eacb.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/f3ed8dde-3902-4d3f-824a-8f00db530827.vsidx 补丁 | 查看 | 原始文档 | blame | 历史
HH.WCS.Mobox3.DSZSH.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
device/ModbusFactory.cs 421 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/140a3f27-91f0-4f76-83cb-8a8da5896f2a.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/340c6236-9991-45c1-b640-67c509d34eff.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/51f15dd6-39b1-4e8d-8d5a-7cdebd5ca9d8.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/c349b9a0-3c00-4a74-bcf5-5ba46f79eacb.vsidx
Binary files differ
.vs/HH.WCS.Mobox3.DSZSH/FileContentIndex/f3ed8dde-3902-4d3f-824a-8f00db530827.vsidx
Binary files differ
HH.WCS.Mobox3.DSZSH.csproj
@@ -235,6 +235,7 @@
    <Compile Include="core\Monitor.cs" />
    <Compile Include="core\WCSCore.cs" />
    <Compile Include="core\WMSCore.cs" />
    <Compile Include="device\ModbusFactory.cs" />
    <Compile Include="device\TcpClientHelper.cs" />
    <Compile Include="models\TN_Outbound_Plan.cs" />
    <Compile Include="models\TN_Record_Table.cs" />
device/ModbusFactory.cs
New file
@@ -0,0 +1,421 @@
using System;
using System.Net.Sockets;
using System.Net;
using Microsoft.Owin.BuilderProperties;
using System.Web.Services.Description;
using Org.BouncyCastle.Utilities.Net;
using System.Web.UI.WebControls.WebParts;
using System.Linq;
using TcpClient = System.Net.Sockets.TcpClient;
namespace HH.WCS.Mobox3.DSZSH.device {
    // 定义Modbus通讯接口
    public interface IModbusCommunicator : IDisposable {
        bool IsConnected { get; }
        void Link(string ipAddress, int port);
        void Disconnect();
        void ReconnectAll();
        // 常用的Modbus功能码方法
        /// <summary>
        /// 读一个或多个线圈,返回一个bit真假数组
        /// </summary>
        /// <param name="startingAddress"></param>
        /// <param name="quantity"></param>
        /// <returns></returns>
        bool[] ReadCoils(int startingAddress, int quantity);
        /// <summary>
        /// 读一个或多个离散输入,返回一个bit真假数组
        /// </summary>
        /// <param name="startingAddress"></param>
        /// <param name="quantity"></param>
        /// <returns></returns>
        bool[] ReadDiscreteInputs(int startingAddress, int quantity);
        /// <summary>
        /// 批量读取或单独读取保持寄存器,返回的是32位int数组
        /// </summary>
        /// <param name="startingAddress"></param>
        /// <param name="quantity"></param>
        /// <returns></returns>
        int[] ReadHoldingRegisters(int startingAddress, int quantity);
        /// <summary>
        /// 读一个或多个输入寄存器,返回一个int32位数组
        /// </summary>
        /// <param name="startingAddress"></param>
        /// <param name="quantity"></param>
        /// <returns></returns>
        int[] ReadInputRegisters(int startingAddress, int quantity);
        /// <summary>
        ///
        /// </summary>
        /// <param name="coilAddress"></param>
        /// <param name="value"></param>
        bool WriteSingleCoil(int coilAddress, bool value);
        bool WriteSingleRegister(int registerAddress, ushort value);
        bool WriteMultipleCoils(int startingAddress, bool[] values);
        bool WriteMultipleRegisters(int startingAddress, int[] values);
    }
    // Modbus通讯方式枚举
    public enum ModbusCommunicationType {
        EasyModbus,
        TcpSocket
    }
    // Modbus通讯工厂类
    public static class ModbusFactory {
        public static IModbusCommunicator CreateCommunicator(ModbusCommunicationType type) {
            switch (type) {
                case ModbusCommunicationType.EasyModbus:
                    return new EasyModbusCommunicator();
                case ModbusCommunicationType.TcpSocket:
                    return new TcpSocketCommunicator();
                default:
                    //throw new ArgumentException("不支持的Modbus通信方式:请选择EasyModbus或TcpSocket");
                    LogHelper.Info("不支持的Modbus通信方式:请选择EasyModbus或TcpSocket");
                    return null;
            }
        }
        static void Test() {
            var communicator = ModbusFactory.CreateCommunicator(ModbusCommunicationType.TcpSocket);
        }
    }
    // EasyModbus实现
    public class EasyModbusCommunicator : IModbusCommunicator {
        private EasyModbus.ModbusClient _modbusClient;
        public bool IsConnected => _modbusClient?.Connected ?? false;
        public void Link(string ipAddress, int port) {
            if (IsConnected) {
                LogHelper.Info($"(ip:{ipAddress}, port:{port})已经连接");
                return;
            }
            _modbusClient = new EasyModbus.ModbusClient(ipAddress, port);
            _modbusClient.Connect();
            if (IsConnected) {
                LogHelper.Info($"连接成功:{ipAddress}:{port}");
            }
            else {
                LogHelper.Info($"连接失败:{ipAddress}:{port}");
            }
        }
        public void Disconnect() {
            if (!IsConnected) {
                LogHelper.Info($"当前没有要断开的连接");
                return;
            }
            _modbusClient?.Disconnect();
            if (IsConnected) {
                LogHelper.Info($"连接成功:{_modbusClient.IPAddress}:{_modbusClient.Port}");
            }
            else {
                LogHelper.Info($"连接失败:{_modbusClient.IPAddress} : {_modbusClient.Port}");
            }
        }
        public void ReconnectAll() {
            if (_modbusClient != null) {
                var ip = _modbusClient.IPAddress;
                var port = _modbusClient.Port;
                Disconnect();
                Link(ip, port);
            }
        }
        public bool[] ReadCoils(int startingAddress, int quantity) {
            bool[] res = new bool[0];
            if (_modbusClient != null && IsConnected) {
                try {
                    res = _modbusClient.ReadCoils(startingAddress, quantity);
                    if (res.Length != 0) {
                        //读取成功
                        LogHelper.Info($"读取成功:ReadCoils");
                    }
                    else {
                        //读取失败
                        LogHelper.Info($"读取失败:ReadCoils");
                    }
                }
                catch (Exception ex) {
                    LogHelper.InfoEx(ex);
                }
            }
            else {
                LogHelper.Info($"设备未连接,读取失败:ReadCoils");
            }
            return res;
        }
        public bool[] ReadDiscreteInputs(int startingAddress, int quantity) {
            bool[] res = new bool[0];
            if (_modbusClient != null && IsConnected) {
                try {
                    res = _modbusClient.ReadDiscreteInputs(startingAddress, quantity);
                    if (res.Length != 0) {
                        //读取成功
                        LogHelper.Info($"读取成功:ReadDiscreteInputs");
                    }
                    else {
                        //读取失败
                        LogHelper.Info($"读取失败:ReadDiscreteInputs");
                    }
                }
                catch (Exception ex) {
                    LogHelper.InfoEx(ex);
                }
            }
            else {
                LogHelper.Info($"设备未连接,读取失败:ReadDiscreteInputs");
            }
            return res;
        }
        public int[] ReadHoldingRegisters(int startingAddress, int quantity) {
            int[] res = new int[0];
            var client = _modbusClient;
            var ip = client.IPAddress;
            var port = client.Port;
            if (client != null && client.Connected) {
                try {
                    //一个寄存器是16位,返回2个int类型
                    res = client.ReadHoldingRegisters(startingAddress, quantity);
                    if (res.Length != 0) {
                        //读取成功
                    }
                    else {
                        //读取失败
                    }
                }
                catch (Exception ex) {
                    //如果请求数量超出保持寄存器的最大数据行数,会报错
                    LogHelper.Info($"发生了异常:{ex.Message},IP:{ip},Port:{port}", "Error");
                }
            }
            else {
                LogHelper.Info($"未找到Modbus设备实例对象:IP:{ip},Port:{port}");
            }
            return res;
        }
        public int[] ReadInputRegisters(int startingAddress, int quantity) {
            int[] res = new int[0];
            var client = _modbusClient;
            var ip = client.IPAddress;
            var port = client.Port;
            if (client != null && client.Connected) {
                try {
                    res = client.ReadInputRegisters(startingAddress, quantity);
                    if (res.Length != 0) {
                        //读取成功
                    }
                    else {
                        //读取失败
                    }
                }
                catch (Exception ex) {
                }
            }
            else {
            }
            return res;
        }
        public bool WriteSingleCoil(int coilAddress, bool value) {
            var res = false;
            var client = _modbusClient;
            var ip = client.IPAddress;
            var port = client.Port;
            if (client != null && client.Connected) {
                try {
                    client.WriteSingleCoil(coilAddress, value);
                    res = value == client.ReadCoils(coilAddress, 1)[0];
                    if (res) {
                        //写入成功
                    }
                    else {
                        //写入失败
                    }
                }
                catch (Exception ex) {
                }
            }
            else {
            }
            return res;
        }
        public bool WriteSingleRegister(int registerAddress, ushort value) {
            var res = false;
            var client = _modbusClient;
            var ip = client.IPAddress;
            var port = client.Port;
            if (client != null && client.Connected) {
                try {
                    client.WriteSingleRegister(registerAddress, value);
                    res = value == client.ReadHoldingRegisters(registerAddress, 1)[0];
                    if (res) {
                        //写入成功
                    }
                    else {
                        //写入失败
                    }
                }
                catch (Exception ex) {
                }
            }
            else {
            }
            return res;
        }
        public bool WriteMultipleCoils(int startingAddress, bool[] values) {
            var res = false;
            var client = _modbusClient;
            var ip = client.IPAddress;
            var port = client.Port;
            if (client != null && client.Connected) {
                try {
                    client.WriteMultipleCoils(startingAddress, values);
                    var dataRead = client.ReadCoils(startingAddress, values.Length);
                    res = values.SequenceEqual(dataRead);
                    if (res) {
                        //写入成功
                    }
                    else {
                        //写入失败
                    }
                }
                catch (Exception ex) {
                }
            }
            else {
            }
            return res;
        }
        public bool WriteMultipleRegisters(int startingAddress, int[] values) {
            var res = false;
            var client = _modbusClient;
            var ip = client.IPAddress;
            var port = client.Port;
            var log = string.Join(",", values.Select(x => x.ToString()));
            if (client != null && client.Connected) {
                try {
                    client.WriteMultipleRegisters(startingAddress, values);
                    var dataRead = client.ReadHoldingRegisters(startingAddress, values.Length);
                    res = values.SequenceEqual(dataRead);
                    if (res) {
                        LogHelper.Info($"写入成功,IP:{ip},Port:{port},{log}");
                    }
                    else {
                        LogHelper.Info($"写入失败,IP:{ip},Port:{port},{log}");
                    }
                }
                catch (Exception ex) {
                    LogHelper.Info($"发生了异常:{ex.Message},IP:{ip},Port:{port},{log}", "Error");
                }
            }
            else {
                LogHelper.Info($"未配置的设备信息,IP:{ip},Port:{port},{log}");
            }
            return res;
        }
        public void Dispose() {
            //_modbusClient?.Dispose();
        }
    }
    // TCPSocket实现
    public class TcpSocketCommunicator : IModbusCommunicator {
        private System.Net.Sockets.TcpClient _tcpClient;
        private NetworkStream _networkStream;
        //public bool IsConnected => _tcpClient?.Connected ?? false;
        public bool IsConnected { get { if (_tcpClient != null) { return true; } else { return false; } } }
        public void Link(string ipAddress, int port) {
            _tcpClient = new System.Net.Sockets.TcpClient();
            _tcpClient.Connect(ipAddress, port);
            _networkStream = _tcpClient.GetStream();
        }
        public void Disconnect() {
            _networkStream?.Close();
            _tcpClient?.Close();
        }
        public void ReconnectAll() {
            if (_tcpClient != null) {
                var ip = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Address.ToString();
                var port = ((IPEndPoint)_tcpClient.Client.RemoteEndPoint).Port;
                Disconnect();
                Link(ip, port);
            }
        }
        // 以下方法需要根据你的Modbus TCP协议具体实现
        public bool[] ReadCoils(int startingAddress, int quantity) {
            // 实现TCP方式读取线圈
            throw new NotImplementedException();
        }
        public bool[] ReadDiscreteInputs(int startingAddress, int quantity) {
            // 实现TCP方式读取离散输入
            throw new NotImplementedException();
        }
        public int[] ReadHoldingRegisters(int startingAddress, int quantity) {
            // 实现TCP方式读取保持寄存器
            throw new NotImplementedException();
        }
        public int[] ReadInputRegisters(int startingAddress, int quantity) {
            // 实现TCP方式读取输入寄存器
            throw new NotImplementedException();
        }
        public bool WriteSingleCoil(int coilAddress, bool value) {
            // 实现TCP方式写入单个线圈
            throw new NotImplementedException();
        }
        public bool WriteSingleRegister(int registerAddress, ushort value) {
            // 实现TCP方式写入单个寄存器
            throw new NotImplementedException();
        }
        public bool WriteMultipleCoils(int startingAddress, bool[] values) {
            // 实现TCP方式写入多个线圈
            throw new NotImplementedException();
        }
        public bool WriteMultipleRegisters(int startingAddress, int[] values) {
            // 实现TCP方式写入多个寄存器
            throw new NotImplementedException();
        }
        public void Dispose() {
            _networkStream?.Dispose();
            //_tcpClient?.Dispose();
        }
    }
}