namespace Modbus.Device { using System; using System.Diagnostics.CodeAnalysis; #if SERIAL using System.IO.Ports; #endif using System.Net.Sockets; using System.Threading.Tasks; using IO; /// /// Modbus IP master device. /// [SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", Justification = "Breaking change.")] public class ModbusIpMaster : ModbusMaster { /// /// Modbus IP master device. /// /// Transport used by this master. private ModbusIpMaster(ModbusTransport transport) : base(transport) { } /// /// Modbus IP master factory method. /// /// New instance of Modbus IP master device using provided TCP client. [SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", Justification = "Breaking change.")] public static ModbusIpMaster CreateIp(TcpClient tcpClient) { if (tcpClient == null) { throw new ArgumentNullException(nameof(tcpClient)); } return CreateIp(new TcpClientAdapter(tcpClient)); } /// /// Modbus IP master factory method. /// /// New instance of Modbus IP master device using provided UDP client. [SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", Justification = "Breaking change.")] public static ModbusIpMaster CreateIp(UdpClient udpClient) { if (udpClient == null) { throw new ArgumentNullException(nameof(udpClient)); } if (!udpClient.Client.Connected) { throw new InvalidOperationException(Resources.UdpClientNotConnected); } return CreateIp(new UdpClientAdapter(udpClient)); } #if SERIAL /// /// Modbus IP master factory method. /// /// New instance of Modbus IP master device using provided serial port. [SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", Justification = "Breaking change.")] public static ModbusIpMaster CreateIp(SerialPort serialPort) { if (serialPort == null) { throw new ArgumentNullException(nameof(serialPort)); } return CreateIp(new SerialPortAdapter(serialPort)); } #endif /// /// Modbus IP master factory method. /// /// New instance of Modbus IP master device using provided stream resource. [SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase", Justification = "Breaking change.")] public static ModbusIpMaster CreateIp(IStreamResource streamResource) { if (streamResource == null) { throw new ArgumentNullException(nameof(streamResource)); } return new ModbusIpMaster(new ModbusIpTransport(streamResource)); } /// /// Reads from 1 to 2000 contiguous coils status. /// /// Address to begin reading. /// Number of coils to read. /// Coils status. public bool[] ReadCoils(ushort startAddress, ushort numberOfPoints) { return base.ReadCoils(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Asynchronously reads from 1 to 2000 contiguous coils status. /// /// Address to begin reading. /// Number of coils to read. /// A task that represents the asynchronous read operation. public Task ReadCoilsAsync(ushort startAddress, ushort numberOfPoints) { return base.ReadCoilsAsync(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Reads from 1 to 2000 contiguous discrete input status. /// /// Address to begin reading. /// Number of discrete inputs to read. /// Discrete inputs status. public bool[] ReadInputs(ushort startAddress, ushort numberOfPoints) { return base.ReadInputs(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Asynchronously reads from 1 to 2000 contiguous discrete input status. /// /// Address to begin reading. /// Number of discrete inputs to read. /// A task that represents the asynchronous read operation. public Task ReadInputsAsync(ushort startAddress, ushort numberOfPoints) { return base.ReadInputsAsync(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Reads contiguous block of holding registers. /// /// Address to begin reading. /// Number of holding registers to read. /// Holding registers status. public ushort[] ReadHoldingRegisters(ushort startAddress, ushort numberOfPoints) { return base.ReadHoldingRegisters(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Asynchronously reads contiguous block of holding registers. /// /// Address to begin reading. /// Number of holding registers to read. /// A task that represents the asynchronous read operation. public Task ReadHoldingRegistersAsync(ushort startAddress, ushort numberOfPoints) { return base.ReadHoldingRegistersAsync(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Reads contiguous block of input registers. /// /// Address to begin reading. /// Number of holding registers to read. /// Input registers status. public ushort[] ReadInputRegisters(ushort startAddress, ushort numberOfPoints) { return base.ReadInputRegisters(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Asynchronously reads contiguous block of input registers. /// /// Address to begin reading. /// Number of holding registers to read. /// A task that represents the asynchronous read operation. public Task ReadInputRegistersAsync(ushort startAddress, ushort numberOfPoints) { return base.ReadInputRegistersAsync(Modbus.DefaultIpSlaveUnitId, startAddress, numberOfPoints); } /// /// Writes a single coil value. /// /// Address to write value to. /// Value to write. public void WriteSingleCoil(ushort coilAddress, bool value) { base.WriteSingleCoil(Modbus.DefaultIpSlaveUnitId, coilAddress, value); } /// /// Asynchronously writes a single coil value. /// /// Address to write value to. /// Value to write. /// A task that represents the asynchronous write operation. public Task WriteSingleCoilAsync(ushort coilAddress, bool value) { return base.WriteSingleCoilAsync(Modbus.DefaultIpSlaveUnitId, coilAddress, value); } /// /// Write a single holding register. /// /// Address to write. /// Value to write. public void WriteSingleRegister(ushort registerAddress, ushort value) { base.WriteSingleRegister(Modbus.DefaultIpSlaveUnitId, registerAddress, value); } /// /// Asynchronously writes a single holding register. /// /// Address to write. /// Value to write. /// A task that represents the asynchronous write operation. public Task WriteSingleRegisterAsync(ushort registerAddress, ushort value) { return base.WriteSingleRegisterAsync(Modbus.DefaultIpSlaveUnitId, registerAddress, value); } /// /// Write a block of 1 to 123 contiguous registers. /// /// Address to begin writing values. /// Values to write. public void WriteMultipleRegisters(ushort startAddress, ushort[] data) { base.WriteMultipleRegisters(Modbus.DefaultIpSlaveUnitId, startAddress, data); } /// /// Asynchronously writes a block of 1 to 123 contiguous registers. /// /// Address to begin writing values. /// Values to write. /// A task that represents the asynchronous write operation. public Task WriteMultipleRegistersAsync(ushort startAddress, ushort[] data) { return base.WriteMultipleRegistersAsync(Modbus.DefaultIpSlaveUnitId, startAddress, data); } /// /// Force each coil in a sequence of coils to a provided value. /// /// Address to begin writing values. /// Values to write. public void WriteMultipleCoils(ushort startAddress, bool[] data) { base.WriteMultipleCoils(Modbus.DefaultIpSlaveUnitId, startAddress, data); } /// /// Asynchronously writes a sequence of coils. /// /// Address to begin writing values. /// Values to write. /// A task that represents the asynchronous write operation public Task WriteMultipleCoilsAsync(ushort startAddress, bool[] data) { return base.WriteMultipleCoilsAsync(Modbus.DefaultIpSlaveUnitId, startAddress, data); } /// /// Performs a combination of one read operation and one write operation in a single MODBUS transaction. /// The write operation is performed before the read. /// Message uses default TCP slave id of 0. /// /// Address to begin reading (Holding registers are addressed starting at 0). /// Number of registers to read. /// Address to begin writing (Holding registers are addressed starting at 0). /// Register values to write. public ushort[] ReadWriteMultipleRegisters( ushort startReadAddress, ushort numberOfPointsToRead, ushort startWriteAddress, ushort[] writeData) { return base.ReadWriteMultipleRegisters( Modbus.DefaultIpSlaveUnitId, startReadAddress, numberOfPointsToRead, startWriteAddress, writeData); } /// /// Asynchronously performs a combination of one read operation and one write operation in a single Modbus transaction. /// The write operation is performed before the read. /// /// Address to begin reading (Holding registers are addressed starting at 0). /// Number of registers to read. /// Address to begin writing (Holding registers are addressed starting at 0). /// Register values to write. /// A task that represents the asynchronous operation. public Task ReadWriteMultipleRegistersAsync( ushort startReadAddress, ushort numberOfPointsToRead, ushort startWriteAddress, ushort[] writeData) { return base.ReadWriteMultipleRegistersAsync( Modbus.DefaultIpSlaveUnitId, startReadAddress, numberOfPointsToRead, startWriteAddress, writeData); } } }