danielkucera / esp-arduino-ebus

67 stars 11 forks source link

Check tcp clients #18

Open ysard opened 1 year ago

ysard commented 1 year ago

Processing is better using a buffer to read & write multiple bytes at a time. I use a separated buffer for this.

danielkucera commented 1 year ago

I don't like this one because in each loop() call I want to read or write only one byte from bus

ysard commented 1 year ago

Ok I understand your concerns, these are big changes that make the code more complex, use buffers which if badly coded cause overflow problems and use more RAM. Furthermore, the documentation is missing.

All things considered, this could be taken as a troll :p

In these conditions you might indeed be attracted to handle the bytes one by one; I assume that the ESP CPU is powerful enough to avoid overflowing the receive buffer. However, this remains to be tested on a network hosting multiple devices (boilers, zone thermostats, temperature sensors, Wi-Fi/GPRS gateways, heat pump, water heater). I have seen such ebusd configurations made by contributors.

I don't know if the ebusd daemon also disables the Nagle agorithm (setNoDelay), but by default the bytes on eBUS and TCP are sent in packets. Processing the bytes one by one generates a large number of small TCP packets and as many ACKs. Besides, the problem here is the latency. ebusd accepts a priori only a 100ms delay to get a response (parameter --receivetimeout). You have the assurance that the packets are sent with a higher priority, but no assurance that the destination OS buries the request and does not buffer them. Not to mention the more frequently called routines (various tests, and calls to millis()).

On a lightly used local network and a good quality WiFi it will work fine. I'm not as confident in unusual configurations such as relayed connections over the Internet or simply several TCP clients connected to the ESP.

For fun and because we should never guess but rather test, I counted the number of packets per second and the number of bytes waiting to be sent returned by available() over a 3 minute period.

boiler off

boiler on, thermostat disconnected

Boiler on with my implementation

The difference in the number of packets is not obvious, there are still a lot of bytes sent alone. However the latency is definitely reduced significantly. We also see that a buffer size of 1024 is more than enough.

Maybe I'm missing something, obviously I will remove buffer sections and keep only code deduplication on your demand.


Regarding the doc, it is written on my dev branch following the Doxygen standard. I cherry-pick the commits to present them to you in independent PRs. Let me know if you want it or not associated to the PR.

danielkucera commented 1 year ago

I appreciate your effort on this but I see the development in another direction - implement data-link layer with arbitration and telegrams, as described in: https://ebus-wiki.org/lib/exe/fetch.php/ebus/spec_prot_12_v1_3_1_e.pdf

I would like to have ebusd send full telegrams, adapter do the arbitration wait for response, ack and send back the response to ebusd in whole, see: https://github.com/john30/ebusd/issues/124 on a separate new port while keeping the old 3333 and 3334.

There is some effort started by @yuhu- : https://github.com/yuhu-/esp8266-arduino-ebus/commit/1a6969a2d240cd844d68c5c2bbafc7ef6a0eb547 But I don't know what else is there in progress.

danielkucera commented 1 year ago

@ysard , would you be able/willing to implement the enh/ens protocol? https://github.com/john30/ebusd/blob/master/docs/enhanced_proto.md

I can offer some money for this.