using MES.Utility.Core; using System; using System.Linq; namespace SharpModbus { public class ModbusMaster : IDisposable { public delegate void OnSendedData(byte[] bytes, string hexString); public event OnSendedData OnSended; public delegate void OnRecivedData(byte[] bytes, string hexString); public event OnRecivedData OnRecived; public static ModbusMaster RTU(SerialSettings settings, int timeout = 400) { var stream = new ModbusSerialStream(settings, timeout); var protocol = new ModbusRTUProtocol(); return new ModbusMaster(stream, protocol); } public static ModbusMaster IsolatedRTU(SerialSettings settings, int timeout = 400) { var stream = new ModbusIsolatedStream(settings, timeout); var protocol = new ModbusRTUProtocol(); return new ModbusMaster(stream, protocol); } public static ModbusMaster TCP(string ip, int port, int timeout = 400) { var socket = Tools.ConnectWithTimeout(ip, port, timeout); var stream = new ModbusSocketStream(socket, timeout); var protocol = new ModbusTCPProtocol(); return new ModbusMaster(stream, protocol); } private readonly IModbusProtocol protocol; private readonly IModbusStream stream; public ModbusMaster(IModbusStream stream, IModbusProtocol protocol) { this.stream = stream; this.protocol = protocol; } public void Dispose() { Tools.Dispose(stream); } public bool ReadCoil(byte slave, ushort address) { return ReadCoils(slave, address, 1)[0]; //there is no code for single read } public bool ReadInput(byte slave, ushort address) { return ReadInputs(slave, address, 1)[0]; //there is no code for single read } public ushort ReadInputRegister(byte slave, ushort address) { return ReadInputRegisters(slave, address, 1)[0]; //there is no code for single read } public ushort ReadHoldingRegister(byte slave, ushort address) { return ReadHoldingRegisters(slave, address, 1)[0]; //there is no code for single read } public bool[] ReadCoils(byte slave, ushort address, ushort count) { return Execute(new ModbusF01ReadCoils(slave, address, count)) as bool[]; } public bool[] ReadInputs(byte slave, ushort address, ushort count) { return Execute(new ModbusF02ReadInputs(slave, address, count)) as bool[]; } public ushort[] ReadInputRegisters(byte slave, ushort address, ushort count) { return Execute(new ModbusF04ReadInputRegisters(slave, address, count)) as ushort[]; } public ushort[] ReadHoldingRegisters(byte slave, ushort address, ushort count) { return Execute(new ModbusF03ReadHoldingRegisters(slave, address, count)) as ushort[]; } public void WriteCoil(byte slave, ushort address, bool value) { Execute(new ModbusF05WriteCoil(slave, address, value)); } public void WriteRegister(byte slave, ushort address, ushort value) { Execute(new ModbusF06WriteRegister(slave, address, value)); } public void WriteCoils(byte slave, ushort address, params bool[] values) { Execute(new ModbusF15WriteCoils(slave, address, values)); } public void WriteRegisters(byte slave, ushort address, params ushort[] values) { Execute(new ModbusF16WriteRegisters(slave, address, values)); } private object Execute(IModbusCommand cmd) { var wrapper = protocol.Wrap(cmd); var request = new byte[wrapper.RequestLength]; var response = new byte[wrapper.ResponseLength]; wrapper.FillRequest(request, 0); OnSended?.Invoke(request, DataHexString(request)); stream.Write(request); var count = stream.Read(response); OnRecived?.Invoke(response, DataHexString(response)); if (count < response.Length) wrapper.CheckException(response, count); return wrapper.ParseResponse(response, 0); } private string DataHexString(byte[] bytes) { if (bytes == null) return string.Empty; return bytes.Select(it => Convert.ToString(it, 16).PadLeft(2, '0').ToUpper()).ToList().GetStrArray(" "); } } }