예제 #1
0
        /// <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();
                }
            }
        }