using System.Collections.Concurrent; using System.Net.Sockets; using NModbus; namespace Bodk.Extensions.Modbus; public class ModbusWrapper { private TcpClient _tcpClient; private IModbusMaster? _modbusMaster; private readonly string _host; private readonly int _port; private readonly int _retries; private readonly int _retryDelay; public ModbusWrapper(string host, int port, int retries = 30, int retryDelay = 1000) { _host = host; _port = port; _retries = retries; _retryDelay = retryDelay; _tcpClient = new TcpClient(); _tcpClient.SendTimeout = 1000; _tcpClient.ReceiveTimeout = 1000; } public async Task ConnectAsync() { if (_tcpClient.Connected) return; await _tcpClient.ConnectAsync(_host, _port); _modbusMaster = new ModbusFactory().CreateMaster(_tcpClient); } private async Task ReconnectAsync() { _tcpClient.Close(); _tcpClient = new TcpClient(); await ConnectAsync(); } public async Task ReadCoilsAsync(ushort startAddress, ushort numberOfPoints) { await ConnectAsync(); if (_modbusMaster is null) await ConnectAsync(); return await _modbusMaster?.ReadCoilsAsync(0, startAddress, numberOfPoints); } public async Task WriteCoilsAsync(ushort startAddress, bool[] values) { await ConnectAsync(); if (_modbusMaster is null) await ConnectAsync(); await _modbusMaster?.WriteMultipleCoilsAsync(0, startAddress, values); } public async Task ReadHoldingRegistersAsync(ushort startAddress, ushort numberOfPoints) { await ConnectAsync(); if (_modbusMaster is null) await ConnectAsync(); return await _modbusMaster?.ReadHoldingRegistersAsync(0, startAddress, numberOfPoints); } public async Task WriteHoldingRegistersAsync(ushort startAddress, ushort[] values) { await ConnectAsync(); if (_modbusMaster is null) await ConnectAsync(); await _modbusMaster?.WriteMultipleRegistersAsync(0, startAddress, values); } }