theelims / ESP32-sveltekit

A simple and extensible framework for ESP32 based IoT projects with a feature-rich, beautiful, and responsive front-end build with Sveltekit, Tailwind CSS and DaisyUI. This is a project template to get you started in no time with a fully integrated build chain.
https://theelims.github.io/ESP32-sveltekit/
Other
118 stars 22 forks source link

How to Display UART Data Sent via EventSource on an Web Interface? #63

Closed thedemoncat closed 2 weeks ago

thedemoncat commented 3 weeks ago

Good afternoon!

I’m just starting to understand the structure of the framework and learning to program for ESP32 with a web interface. I’m working on a task where I’m stuck and could use some guidance.

There is a device that sends a data stream via UART in JSON format every second. As suggested in the documentation, I created a new class UartConnectService, where I initialize the UART connection through begin(). Then, I start a task for continuous data stream reading using RTOS:

xTaskCreatePinnedToCore(
    this->_loop(),            // Function that should be called
    "UartConnect Loop",       // Name of the task (for debugging)
    4096,                     // Stack size (bytes)
    this,                     // Pass reference to this class instance
    (configMAX_PRIORITIES - 1), // Task priority
    nullptr,                  // Task handle
    1 // Pin to application core
);

In the _loop method, data from UART is obtained. I checked this during debugging, and everything works correctly.

Then, I want to send this data via EventSource to the web interface:

char data[1024]; 
JsonDocument doc;
while (true) {
    const int len = uart_read_bytes(UART_NUM_1, (uint8_t*)data, sizeof(data) - 1, pdMS_TO_TICKS(100));
    if (len > 0) {
        data[len] = '\0';
        // Serial.println(data);
        DeserializationError error = deserializeJson(doc, data);
        if (!error) {
            auto jsonObject = doc.as<JsonObject>();
            _socket->emitEvent(SSVC_OPEN_CONNECT_EVENT, jsonObject);
        } else {
            #ifdef SERIAL_INFO
                Serial.print(F("JSON parsing error: "));
                Serial.println(error.f_str());
            #endif
        }
    }
    vTaskDelay(pdMS_TO_TICKS(500));
}

There are no compilation errors, and I think _socket->emitEvent(SSVC_OPEN_CONNECT_EVENT, jsonObject); works correctly.

However, I can’t figure out how to display this data on the web interface.

Here’s a similar example I implemented using AsyncEventSource*:

AsyncEventSource events("/events");
....
events.send(jsonString.c_str(), nullptr, millis());

Then, I subscribed to it in the component:

onMount(() => {
    let url = '/events';
    const eventSource = new EventSource(url);

    eventSource.onmessage = (event) => {
        const parsedData = JSON.parse(event.data);
        dispatch("dataReceived", parsedData);
    };

    return () => eventSource.close();
});
...

// show

<pre>{JSON.stringify(data, undefined, 2)}</pre>

But I can’t figure out how to implement this through the framework.

Could you provide an example of how to display this data? I would be grateful for any assistance with this issue.

theelims commented 3 weeks ago

There are few things to consider. Firstly, you must call _socket.registerEvent(SSVC_OPEN_CONNECT_EVENT); in your class UartConnectService. This is best located in a begin() function. Otherwise the event never gets send out.

Secondly the "Event Socket" is not using Server Send Events (SSE) as protocol but is rather a custom protocol sitting on top of a websocket connection. See https://theelims.github.io/ESP32-sveltekit/stores/#event-socket for the client side implementation. It is conveniently implemented as Svelte store. You can either subscribe to the socket store on the site or svelte component directly, or create an custom store which is connected in the main +layout.svelte. Have a look at the Telemetry or Analytics stores on how to implement that.

For debugging you can enable the -D EVENT_USE_JSON=1 flag in platformio.ini to see the communication in the browser debug tab.

thedemoncat commented 2 weeks ago

Thank you very much! I figured out how to transfer the data.