ayushsharma82 / ESP-DASH

Blazing fast library to create a functional, on-device dashboard for ESP8266 / ESP32 / RP2040
https://espdash.pro
GNU General Public License v3.0
978 stars 200 forks source link

Arduino 3 / ESP-IDF 5 compatibility #210

Closed mathieucarbou closed 6 months ago

mathieucarbou commented 7 months ago

This PR updates some project files (CI and library.json) to ensure compatibility with Arduino 3 / ESP-IDF 5.

The project itself does not require any change (I tested the benchmark example on ESP32S3 with Arduino 3 RC1), except the library.json for PlatformIO projects, but these dependencies must be used, which have been updated to support Arduino 3 / ESP-IDF 5:

Example:

lib_deps = 
  mathieucarbou/Async TCP @ ^3.0.2
  mathieucarbou/ESP Async WebServer @ 2.9.3

You can see the PR build in my fork with the new CI files: https://github.com/mathieucarbou/ayushsharma82-ESP-DASH/actions/runs/8774146477

ayushsharma82 commented 6 months ago

@mathieucarbou , Thanks, I'll merge this PR soon.

I'm re-working WebSerial which might delay some things. It's getting a complete makeover 😄.

mathieucarbou commented 6 months ago

@mathieucarbou , Thanks, I'll merge this PR soon.

I'm re-working WebSerial which might delay some things. It's getting a complete makeover 😄.

FYI the dependencies must be updated since - I ~will refresh~ have refreshed the PR.

Good to know for WebSerial ! I am using an equivalent one on 2 big projets so if you want me to include it to show case and test for bugs let me know :-)

I added some things like logo, local command history with arrow up & down, etc

ayushsharma82 commented 6 months ago

@mathieucarbou Sure, your feedback will be helpful. I'll send it to you this week.

Local command history sounds like a wonderful idea! I'll see if it can be implemented after roll out.

ayushsharma82 commented 6 months ago

Here's a sneak peek:

Screenshot 2024-05-11 at 1 31 48 AM
mathieucarbou commented 6 months ago

I've updated the PR again to account for the new Arduino v3 rc2, and espressif platform 6.7.0

mathieucarbou commented 6 months ago

Switched to 3.0.0-rc3.

FYI Arduino 3 is supposed to be released next week if everything is ok, but I doubt it because with someone else we found a serious bug (wifi not working on a lot of boards) so it might be delayed.

In any case, I don't you might want to wait for Arduino 3 release before merging it... Should be soon.

ayushsharma82 commented 6 months ago

I'll be merging it in a 2-3 days - no time to test myself.

Btw, WebSerial V2 release candidate is in v2 branch: https://github.com/ayushsharma82/WebSerial/tree/v2

mathieucarbou commented 6 months ago

Ok! I've looked a little at the source code and I have a few comments:

Mathieu.

ayushsharma82 commented 6 months ago

you could provide a callback with a String (or char*) that would be easier to process because anyway the only possible thing the WS callback would receive is a command

Yeah, I can add it as another callback.

I am really wondering about the double buffering mechanism

Really didn't want to use double buffering mechanism too but the main focus of this release was to make it stable somehow, It ultimately came to an over-engineered approach but it is stable afaik. If you know of any other approach, we can still revamp it.

The Print Problem

Even if we are using println or printf functions - we are actually getting single byte write commands in the library. It was not sending the whole log line in one go, this made it necessary to buffer these into chunks.

The very first version of WebSerial had no buffering which caused a lot of problems. You know why - because people tend to use a lot of print functions and the WS queue is overflown quickly.

Dual Buffer Roles

Role of Print Buffer:

Buffers the incoming single byte writes into a whole message packet and regularly flushes the received data into global buffer by marking it a as a 'row'. ( This is quite essential in WebSerial Pro because timestamps are tagged now ). It also lets us free on depending for a \n new line character to close the row.

Role of Global Buffer:

The only reason for using a global buffer was 'performance' and WS queue limitation. ESP really sucks in sending bursts of data via Websockets, therefore we batch all rows into a single global buffer that decreases load on the WebSocket server.

ayushsharma82 commented 6 months ago

Regarding Buffer Mutex

This was really just a shot in the dark. What are the approaches to this - apart from leaving it to the user?

mathieucarbou commented 6 months ago

Yes there is a lot of tradeoffs here I agree.

For what is worth, write(c) is not called.

image

My logger impl if buffering and forwarding to registered Print implementations:

image

and in the WebSerial class I only have:

image

Once write(const uint8_t* buffer, size_t size) is overridden, most of the Print methods are using it.

mathieucarbou commented 6 months ago

Also, to solve the dual core issue with potentially 2 tasks on different cores calling write(), if buffering is not handled on caller site, and each core can write as they want, the common buffer behind can contain a mix of characters from both. To correctly fix that you would need to maintain a buffer per core, and get the current core with xPortGetCoreID().

So that's a double buffer...

Personally, here is what I would do:

size_t WebSerialClass::write(uint8_t m) {
  log_e("use the buffered method instead to not overload WS queue, or set #define WS_ALLOW_WRITE_CHAR to really allow this, knowing what you are doing, or fix the caller stack to go through the write(buffer) method, writing lines instead of characters");
  assert(false);
}

FYI: this is what I was using for several months locally and it worked fine. This also helped me correctly find callers I needed to fix thanks to the call stack

Something similar to a print buffer collector, but which could also detect EOL and flush them in the write method.

For example, such class could be improved to detect EOL and then flush the content to the write method of the delegate passed as parameter, which could be any print or WebSerial itself.

  class WebSerialBuffer : public Print {
    public:
      WebSerialBuffer(Print delegate) { _buffer.reserve(WS_BUFFER_SIZE); };
      size_t write(const uint8_t* p, size_t n) override { return _buffer.concat(reinterpret_cast<const char*>(p), n) ? n : 0; }
      size_t write(uint8_t c) override { return _buffer.concat(static_cast<char>(c)) ? 1 : 0; }
      const String& buffer() const { return _buffer; }

    private:
      String _buffer;
  };

Such buffering would occur on caller side and be memory-collected once not needed anymore.

mathieucarbou commented 6 months ago

@ayushsharma82 : Arduino 3 is out, I've updated the CI build. It is not yet available through espressif / PIO (will take more time for that) - see https://github.com/espressif/arduino-esp32/issues/8796#issuecomment-2133972719

ayushsharma82 commented 6 months ago

@mathieucarbou I guess I'll just leave buffer mutex issue to the user itself. Seems very hard to tackle on our own.

Also, the time has come - I'll update all my major libraries to use your fork of AsyncWebServer :)

ayushsharma82 commented 6 months ago

@mathieucarbou , I updated CI of v2 branch of WebSerial as well but it failed at arduino step, what could be the issue?

Screenshot 2024-05-29 at 10 01 35 PM
mathieucarbou commented 6 months ago

@mathieucarbou , I updated CI of v2 branch of WebSerial as well but it failed at arduino step, what could be the issue?

Screenshot 2024-05-29 at 10 01 35 PM

That's the Arduino CI part that is failing. I am wondering if this is caused by your fork of the gitbub action ?

FYI here is the CI setup I use in my WebSerial fork (I dropped support for esp8266 - you would just need to add it back)

https://github.com/mathieucarbou/WebSerialLite/blob/main/.github/workflows/ci.yml

mathieucarbou commented 6 months ago

It is also failing for ESP-DASH....

mathieucarbou commented 6 months ago

I have updated my fork and I have the same issue... https://github.com/mathieucarbou/ayushsharma82-ESP-DASH/actions/runs/9289998149

Wondering if something has changed on their side...

ayushsharma82 commented 6 months ago

Probably something is down or changed on their side.

mathieucarbou commented 6 months ago

I have fixed it in PR https://github.com/ayushsharma82/ESP-DASH/pull/214 by using the same mechanism I use in my other projects. This is more verbose but it works and gives more control.