示例#1
0
        public async Task WriteMultipleCoils(ushort address, bool[] states, CancellationToken token = default)
        {
            ThrowIfDisposed();

            ThrowIfNotConnected();

            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            var header = CreateHeader();
            var frame  = new RequestAdu
            {
                Header = header,
                Pdu    = new RequestWriteMultipleCoils
                {
                    Address    = address,
                    CoilStates = states
                }
            };

            var written = _writer.WriteFrame(frame);

            _connection.Transport.Output.Advance(written);

            var waitForResponse = WaitForResponse <ResponseWriteMultipleCoils>(frame, token).ConfigureAwait(false);

            var result = await _connection.Transport.Output.FlushAsync(token).ConfigureAwait(false);

            var response = await waitForResponse;

            // TODO: check if quantity and adress are correct?
        }
示例#2
0
        public async Task <bool> WriteSingleCoil(ushort address, bool state, CancellationToken token = default)
        {
            ThrowIfDisposed();

            ThrowIfNotConnected();

            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            var header = CreateHeader();
            var frame  = new RequestAdu
            {
                Header = header,
                Pdu    = new RequestWriteSingleCoil
                {
                    Address   = address,
                    CoilState = state,
                }
            };

            var written = _writer.WriteFrame(frame);

            _connection.Transport.Output.Advance(written);

            var waitForResponse = WaitForResponse <ResponseWriteSingleCoil>(frame, token).ConfigureAwait(false);

            var result = await _connection.Transport.Output.FlushAsync(token).ConfigureAwait(false);

            var response = await waitForResponse;

            return(response.Result);
        }
示例#3
0
        public async Task <ushort[]> ReadInputRegisters(ushort address, ushort quantity, CancellationToken token = default)
        {
            ThrowIfDisposed();

            ThrowIfNotConnected();

            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            var header = CreateHeader();
            var frame  = new RequestAdu
            {
                Header = header,
                Pdu    = new RequestReadInputRegisters
                {
                    Address  = address,
                    Quantity = quantity,
                }
            };

            var written = _writer.WriteFrame(frame);

            _connection.Transport.Output.Advance(written);

            var waitForResponse = WaitForResponse <ResponseReadInputRegisters>(frame, token).ConfigureAwait(false);
            var flushResult     = await _connection.Transport.Output.FlushAsync(token).ConfigureAwait(false);

            var response = await waitForResponse;

            return(response.Results);
        }
示例#4
0
        public void ModbusFrameWriter_WriteFrame_CorrectlyWritesAReadInputRegistersRequest()
        {
            // Given
            var request = new RequestAdu
            {
                Header = new Header(transactionID: 1, unitID: 4),
                Pdu    = new RequestReadInputRegisters
                {
                    Address  = 0x0040,
                    Quantity = 0x000A,
                },
            };
            var arraybuffer = new ArrayBufferWriter <byte>();

            // When
            var writer   = new ModbusFrameWriter(arraybuffer);
            var position = writer.WriteFrame(request);

            arraybuffer.Advance(position);

            // Then
            var data = arraybuffer.WrittenSpan.ToArray();

            Assert.Equal(
                new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x04, 0x04, 0x00, 0x40, 0x00, 0x0A },
                data
                );
        }
示例#5
0
        public void ModbusFrameWriter_WriteFrame_CorrectlyWritesAWriteSingleCoilRequest()
        {
            // Given
            var request = new RequestAdu
            {
                Header = new Header(transactionID: 1, unitID: 4),
                Pdu    = new RequestWriteSingleCoil
                {
                    Address   = 0x0041,
                    CoilState = true,
                },
            };
            var arraybuffer = new ArrayBufferWriter <byte>();

            // When
            var writer   = new ModbusFrameWriter(arraybuffer);
            var position = writer.WriteFrame(request);

            arraybuffer.Advance(position);

            // Then
            var data = arraybuffer.WrittenSpan.ToArray();

            Assert.Equal(
                new byte[] { 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x04, 0x05, 0x00, 0x41, 0xFF, 0x00 },
                data
                );
        }
示例#6
0
        public async Task <List <bool> > ReadDiscreteInputs(ushort address, ushort quantity, CancellationToken token = default)
        {
            ThrowIfDisposed();

            ThrowIfNotConnected();

            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }

            var header = CreateHeader();
            var frame  = new RequestAdu
            {
                Header = header,
                Pdu    = new RequestReadDiscreteInputs
                {
                    Address  = address,
                    Quantity = quantity,
                }
            };

            var written = _writer.WriteFrame(frame);

            _connection.Transport.Output.Advance(written);

            var waitForResponse = WaitForResponse <ResponseReadDiscreteInputs>(frame, token).ConfigureAwait(false);
            var flushResult     = await _connection.Transport.Output.FlushAsync(token).ConfigureAwait(false);

            var response = await waitForResponse;

            var bits   = new BitArray(response.Coils);
            var result = new List <bool>();

            for (var i = 0; i < quantity; i++)
            {
                result.Add(bits[i]);
            }

            return(result);
        }
示例#7
0
        private async Task <T> WaitForResponse <T>(RequestAdu request, CancellationToken token = default) where T : IResponsePdu
        {
            var header = request.Header;
            var source = new TaskCompletionSource <ResponseAdu>(TaskCreationOptions.RunContinuationsAsynchronously);

            if (!_transactions.TryAdd(header.TransactionID, source))
            {
                throw new InvalidOperationException("Can't start transaction.");
            }

            var race = await Task.WhenAny(source.Task, Task.Delay(_timeout, token)).ConfigureAwait(false);

            if (race == source.Task)
            {
                var responseFrame = await source.Task;

                if (responseFrame.Pdu is T response)
                {
                    return(response);
                }
                else if (responseFrame.Pdu is ResponseError error)
                {
                    throw new ModbusRequestException(error.ErrorCode);
                }
                else
                {
                    throw new ModbusRequestException("Unknown response");
                }
            }
            else
            {
                source.SetCanceled();
                _transactions.Remove(header.TransactionID, out var _);
                throw new TimeoutException();
            }
        }
示例#8
0
 public int WriteFrame(RequestAdu frame) => frame.Pdu switch
 {