* Refactor and fix PID sensor (PID_USE_LOCAL_SENSOR) read race condition
Refactor PID since it was calling pid.tick willy-nilly upon demand
from MQTT and the web instead of on a periodic basis (and was being
called with time interval of 0 when those times lined up!). Refactor
web/mqtt display because there was shared code (that code turned out
to be misguided and belonged in Every_Second loop, but now we are also
similar to 39 thermostat)
Logging revealed that the vast majority of the time the sensor JSON
was parsed to obtain current sensor data when using PID local sensor,
it was failing to parse (and it would typically only work for a second
around TELE_PERIOD, but even then, not reliably). This bug almost
certainly affects xdrv_39_thermostat too, but using
xsns_75_prometheus.ino as a template, we are able to update PV once
per second, which allows us to be a lot more responsive. There is no
danger of being "too responsive" because that's the point of PID, and
the PID loop already scales feedback by interval between ticks.
* Reduce logging of PID now that query side-effects removed
* Comment out all new logging, but leave present for next debugger
- 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>