using System.Net.Sockets; using System.Net; using System.Threading; using System; using LogoForceTestApp.Services.Interfaces; using NModbus; using LogoForceTestApp.Services.Interfaces.Events; namespace LogoForceTestApp.Services { public class ModbusTcpSlaverService : IModbusTcpSlaverService { private IModbusSlave _modbusSlave; private TcpListener slaveTcpListener; public event EventHandler> CoilDiscretesHandler; public event EventHandler> InputRegistersHandler; public event EventHandler> HoldeRegistersHandler; private CancellationTokenSource _cancellationTokenSource; public ModbusTcpSlaverService() { _cancellationTokenSource = new CancellationTokenSource(); } /// /// create and start the TCP slave /// 默认创建所有监听所有网卡ip地址和localhost /// 默认端口号为502 /// 默认slaveId为1 /// public void CreateModbusTcpSlave(string ip = default, byte slaveId = 1, int port = 502) { IPAddress address; if (ip == default) { address = IPAddress.Any; } else { var ret = IPAddress.TryParse(ip, out address); if (!ret) { throw new ArgumentException("ip 参数错误"); } } slaveTcpListener = new TcpListener(address, port); slaveTcpListener.Start(); var factory = new ModbusFactory(); //var tcpClient = new TcpClient("",5555); //var master = factory.CreateMaster(tcpClient); var network = factory.CreateSlaveNetwork(slaveTcpListener); var slaveStorage = new SlaveStorage(); slaveStorage.InputRegisters.StorageOperationOccurred += InputRegisters_StorageOperationOccurred; slaveStorage.HoldingRegisters.StorageOperationOccurred += HoldingRegisters_StorageOperationOccurred; slaveStorage.CoilInputs.StorageOperationOccurred += CoilInputs_StorageOperationOccurred; slaveStorage.CoilDiscretes.StorageOperationOccurred += CoilDiscretes_StorageOperationOccurred; ; var slave = factory.CreateSlave(1, slaveStorage); network.AddSlave(slave); var listenTask = network.ListenAsync(_cancellationTokenSource.Token); _modbusSlave = slave; } private void CoilDiscretes_StorageOperationOccurred(object sender, StorageEventArgs args) { //Debug.Write($"DANFOSS CoilDiscretes: {args.Operation} starting at {args.StartingAddress},count {args.Points.Length}"); CoilDiscretesHandler?.Invoke(this, args); } private void CoilInputs_StorageOperationOccurred(object sender, StorageEventArgs args) { //LogUtil.WriteInfo($"DANFOSS CoilInputs: {args.Operation} starting at {args.StartingAddress},count {args.Points.Length}"); } private void HoldingRegisters_StorageOperationOccurred(object sender, StorageEventArgs args) { //HoldeRegistersHandler?.Invoke(this, args); //var x=args.Points[32]; } private void InputRegisters_StorageOperationOccurred(object sender, StorageEventArgs args) { //LogUtil.WriteInfo($"DANFOSS Input registers: {args.Operation} starting at {args.StartingAddress},count {args.Points.Length}"); InputRegistersHandler?.Invoke(this, args); } public IModbusSlave GetModbusSlaveByIp() { return _modbusSlave; } /// /// 写入32位整数 /// /// /// public void WriteParameter(ushort startAddress, int value) { if (_modbusSlave == null) { throw new Exception("没有创建modbus slave"); } var bytes = BitConverter.GetBytes(value); var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0); var second = BitConverter.ToUInt16(new[] { bytes[2], bytes[3] }, 0); _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first, second }); } public void WriteCoilParameter(ushort startAddress, bool value) { if (_modbusSlave == null) { throw new Exception("没有创建modbus slave"); } _modbusSlave.DataStore.CoilInputs.WritePoints(startAddress, new bool[] { value }); } /// /// 写入32位正整数 /// /// /// public void WriteParameter(ushort startAddress, uint value) { if (_modbusSlave == null) { throw new Exception("没有创建modbus slave"); } var bytes = BitConverter.GetBytes(value); var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0); var second = BitConverter.ToUInt16(new[] { bytes[2], bytes[3] }, 0); _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first, second }); } /// /// 写入16位正整数 /// /// /// public void WriteParameter(ushort startAddress, ushort value) { if (_modbusSlave == null) { throw new Exception("没有创建modbus slave"); } var bytes = BitConverter.GetBytes(value); var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0); _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first }); } /// /// 写入16位整数 /// /// /// public void WriteParameter(ushort startAddress, short value) { if (_modbusSlave == null) { throw new Exception("没有创建modbus slave"); } var bytes = BitConverter.GetBytes(value); var first = BitConverter.ToUInt16(new[] { bytes[0], bytes[1] }, 0); _modbusSlave.DataStore.HoldingRegisters.WritePoints(startAddress, new[] { first }); } public void Dispose() { slaveTcpListener.Stop(); _cancellationTokenSource.Cancel(); } } }