/// <summary> /// Method to send a Modbus write request to a Modbus slave providing common /// communication setup and associated exception handling (logging). /// A TCP client is created and used to send the request to the Modbus TCP client. /// The following requests are supported: /// /// Multiple Coils /// Multiple Holding Register /// /// Additional datatypes with read / write access (coils and holding registers) are supported: /// /// Bool (multiple coils) /// Bytes (multiple holding registers) /// Short (multiple holding registers) /// UShort (multiple holding registers) /// Int32 (multiple holding registers) /// UInt32 (multiple holding registers) /// Float (multiple holding registers) /// Double (multiple holding registers) /// Long (multiple holding registers) /// ULong (multiple holding registers) /// /// </summary> /// <param name="request">The <see cref="ModbusRequestData"/> data.</param> /// <param name="data">The data value.</param> /// <param name="function">The function name.</param> /// <returns>A task returning an action method result.</returns> protected async Task <IActionResult> ModbusWriteArrayRequest <T>(ModbusRequestData request, T[] data, string function) { try { request.Master = _client.RtuMaster; if (_client.Connect()) { switch (function) { case "WriteCoilsAsync": { bool[] values = (bool[])Convert.ChangeType(data, typeof(bool[])); await _client.WriteMultipleCoilsAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteHoldingRegistersAsync": { ushort[] values = (ushort[])Convert.ChangeType(data, typeof(ushort[])); await _client.WriteMultipleRegistersAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteBoolArrayAsync": { bool[] values = (bool[])Convert.ChangeType(data, typeof(bool[])); await _client.WriteBoolArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteBytesAsync": { byte[] values = (byte[])Convert.ChangeType(data, typeof(byte[])); await _client.WriteBytesAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteShortArrayAsync": { short[] values = (short[])Convert.ChangeType(data, typeof(short[])); await _client.WriteShortArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteUShortArrayAsync": { ushort[] values = (ushort[])Convert.ChangeType(data, typeof(ushort[])); await _client.WriteUShortArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteInt32ArrayAsync": { int[] values = (int[])Convert.ChangeType(data, typeof(int[])); await _client.WriteInt32ArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteUInt32ArrayAsync": { uint[] values = (uint[])Convert.ChangeType(data, typeof(uint[])); await _client.WriteUInt32ArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteFloatArrayAsync": { float[] values = (float[])Convert.ChangeType(data, typeof(float[])); await _client.WriteFloatArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteDoubleArrayAsync": { double[] values = (double[])Convert.ChangeType(data, typeof(double[])); await _client.WriteDoubleArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteLongArrayAsync": { long[] values = (long[])Convert.ChangeType(data, typeof(long[])); await _client.WriteLongArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } case "WriteULongArrayAsync": { ulong[] values = (ulong[])Convert.ChangeType(data, typeof(ulong[])); await _client.WriteULongArrayAsync(request.Slave.ID, request.Offset, values); _logger.LogTrace($"{function}() OK."); return(Ok(request)); } default: _client.Disconnect(); _logger.LogError($"RTU master write request {function}() not supported."); return(NotFound($"RTU master write request {function}() not supported.")); } } else { _logger.LogError($"RTU master ({request.Master.SerialPort}) not open."); return(NotFound("RTU master COM port not open.")); } } catch (UnauthorizedAccessException uae) { _logger.LogError(uae, $"{function}() Unauthorized Access Exception."); return(NotFound($"Unauthorized Access Exception: {uae.Message}")); } catch (ArgumentOutOfRangeException are) { _logger.LogError(are, $"{function}() Argument out of Range Exception."); return(BadRequest($"Argument out of Range Exception: {are.Message}")); } catch (ArgumentException aex) { _logger.LogError(aex, $"{function}() Argument Exception."); return(BadRequest($"Argument Exception: {aex.Message}")); } catch (NModbus.SlaveException mse) { _logger.LogError(mse, $"{function}() Modbus SlaveException."); return(StatusCode(502, $"Modbus SlaveException: {mse.Message}")); } catch (System.IO.IOException ioe) { _logger.LogError(ioe, $"{function}() IO Exception."); return(StatusCode(500, $"IO Exception: {ioe.Message}")); } catch (TimeoutException tex) { _logger.LogError(tex, $"{function}() Timeout Exception."); return(StatusCode(500, $"Timeout Exception: {tex.Message}")); } catch (Exception ex) { _logger.LogError(ex, $"{function}() Exception."); return(StatusCode(500, $"Exception: {ex.Message}")); } finally { if (_client.Connected) { _client.Disconnect(); } } }