Prevent from sending more then one Modbus TCP response
for a single request.
This might happen in the following scenario where,
shortly after the first response has been sent (4),
the second one will be send (8) (note the same
'TransactionId') triggered by the response to the
'ModbusSend' request issued by Berry (5).
The log excerpt from such a situation:
(1) 21:13:20.510 MBS: MBRTCP to Modbus TransactionId:520, deviceAddress:4, functionCode:3, startAddress:8193, count:1, recvCount:1, recvBytes:2
(2) 21:13:20.523 MBS: Serial Send: 04 03 20 01 00 01 DE 5F
(3) 21:13:20.647 MBS: Serial Received: 04 03 02 0A 28 72 FA
(4) 21:13:20.652 MBS: MBRTCP from Modbus TransactionId:520, deviceAddress:4, writing:11 bytes to client (error:0)
(5) 21:13:20.724 CMD: Grp 0, Cmd 'MODBUSSEND', Idx 1, Len 89, Pld -99, Data '{"deviceAddress":4, "functionCode":6, "startAddress":8192, "type":"uint16", "Values":[6]}'
(6) 21:13:20.743 MBS: Serial Send: 04 06 20 00 00 06 02 5D
(7) 21:13:21.009 MBS: Serial Received: 04 06 20 00 00 06 02 5D
(8) 21:13:21.014 MBS: MBRTCP from Modbus TransactionId:520, deviceAddress:4, writing:12 bytes to client (error:0)
Use 'tcp_transaction_id' field to denote that we already
sent a response.
Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>
- Fix cases where the subsequent Modbus packet
can be send to the serial port (triggered either by
'ModbusSend' command or request from TCP bridge)
before an answer was received to the previous packet.
This can happen in a setup where simultaneously:
- two (or more) modbus TCP clients are sending requests
through the modbus-proxy [1] to Tasmota,
- ModbusSend commands are executed (e.g. using Berry).
Log excerpt (from build with TASMOTAMODBUSDEBUG enabled):
14:51:18.940 MBS: Serial Send: 04 03 01 00 00 09 84 65
14:51:19.054 MBS: Serial Send: 04 03 10 0A 00 05 A1 5E
14:51:19.136 MBS: Serial Received: 04 03 0A 00 00 00 D0 00 00 01 AB 00 00 89 62
Fix adds 'waitingForAnswerFromSerial' flag which is set after
we send data to the serial port and prevents sending another
requests before we receive an answer or timeout happened.
Fix stores temporarily a 'ModbusSend' command data and tries
to execute it after Modbus response has been received or
timeout has happened.
- Add 'ModbusSerialTimeout' command which sets timeout in [ms]
for how long we will be waiting for an answer from the client device.
Default value is 1000 [ms] and it is not restored after reboot.
- Sends error 11 (0xB) (as TCP response) when no answer was received
from the serial port within the timeout set by 'ModbusSerialTimeout'
command.
- Add Modbus 'TransactionId' to the logging.
[1] https://github.com/tiagocoutinho/modbus-proxy
Signed-off-by: Damian Wrobel <dwrobel@ertelnet.rybnik.pl>