s00500 / ESPUI

A simple web user interface library for ESP32 and ESP8266

Home Page:https://valencia.lbsfilm.at/midterm-presentation/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OTA Update

robvoi opened this issue · comments

Hi.
is it possible to have ESP32 UI combined with OTA Updates?
If so, does someone have n example on how to do it?

Thanks!

I am also interested in it very much. Tried couple of different OTAs without success.... Please help.

I am also interested in it very much. Tried couple of different OTAs without success.... Please help.

Have you tried a different OTA with own webserver on a different port?

Dear, I tried AsyncElegantOTA... no success... port 8080..
Thanks.

Problem seems that all OTA implementations try to initiate <WebServer.h>.
Which is initiated already. It may be possible to adapt one of the libraries. But not sure what exactly has to be changed.
@s00500 I guess you have more knowledge that we have. Especially on the WebServer part. Any idea on an approach?

Would love this also, i went down a similar rabbit hold last night trying different solutions that are out there but ran into conflicts, ElegantOTA was the only one i could get to compile ok as i'm using asyncwifimanger but that won't work as ESPUI is starting the webserver itself and as mentioned it's already initiated so the other solutions don't compile out of the box.

Well to avoid the Webserver conflict (which would be inspected in more detail) I could recommend you to use HTTP GET style OTA, where the ESP would fetch the update binary from an external server

This would indeed be good. But the device I am working on is in AP mode.

Wouldn't be that hard to support file upload @s00500 like in this WebUpdate Example?

Just as a note: As a workaround I have been doing this so far:

#include <ESPUI.h>

#if defined(ESP32)
#include <Update.h>
#else
#include <Updater.h>
#endif

const char* OTA_INDEX PROGMEM
    = R"=====(<!DOCTYPE html><html><head><meta charset=utf-8><title>OTA</title></head><body><div class="upload"><form method="POST" action="/ota" enctype="multipart/form-data"><input type="file" name="data" /><input type="submit" name="upload" value="Upload" title="Upload Files"></form></div></body></html>)=====";

void handleOTAUpload(AsyncWebServerRequest* request, String filename, size_t index, uint8_t* data, size_t len, bool final)
{
    if (!index)
    {
        Serial.printf("UploadStart: %s\n", filename.c_str());
         // calculate sketch space required for the update, for ESP32 use the max constant
#if defined(ESP32)
        if (!Update.begin(UPDATE_SIZE_UNKNOWN))
#else
        const uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
        if (!Update.begin(maxSketchSpace))
#endif
        {
            // start with max available size
            Update.printError(Serial);
        }
#if defined(ESP8266)
        Update.runAsync(true);
#endif
    }

    if (len)
    {
        Update.write(data, len);
    }

    // if the final flag is set then this is the last frame of data
    if (final)
    {
        if (Update.end(true))
        {
            // true to set the size to the current progress
            Serial.printf("Update Success: %ub written\nRebooting...\n", index + len);
            ESP.restart();
        }
        else
        {
            Update.printError(Serial);
        }
    }
}

void setupGUI()
{
    ESPUI.begin("GUI"); // It is important that ESPUI.begin(...) is called first so that ESPUI.server is initalized

    ESPUI.server->on("/ota", 
        HTTP_POST, 
        [](AsyncWebServerRequest* request) { request->send(200); }, 
        handleOTAUpload);

    ESPUI.server->on("/ota", 
        HTTP_GET, 
        [](AsyncWebServerRequest* request) {
            AsyncWebServerResponse* response = request->beginResponse_P(200, "text/html", OTA_INDEX);
            request->send(response);
        }
    );
}

void setup() {
  setupGUI();
}

void loop() {
  // put your main code here, to run repeatedly:
}

Just as a note: As a workaround I have been doing this so far:

Thanks a lot for your post. I tried including your code. But it doesn't compile.
Which includes do you use?
Or can you maybe post a complete sketch with update+ESPUI.

@robvoi I've updated the example code (there where some braces missing after setupGUI)

It works. That's fantastic.

You still have a typo in the code Updater.h -> Update.h
Or are you using a different update library (could explain the below)

Had to remove Update.runAsync(true); as I got an error when compiling. 'class UpdateClass' has no member named 'runAsync'

No idea why.

You still have a typo in the code Updater.h -> Update.h
Or are you using a different update library (could explain the below)

Had to remove Update.runAsync(true); as I got an error when compiling. 'class UpdateClass' has no member named 'runAsync'

For ESP8266 you need to include #include <Updater.h> for ESP32 #include <Update.h> also for ESP32 Update.runAsync(true); is not needed and also

const uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
        if (!Update.begin(maxSketchSpace))

should be replaced by

        if (!Update.begin(UPDATE_SIZE_UNKNOWN))

I have updated the example to work for both ESP32 and ESP8266

Great! thanks guys....

commented

Hi,
I had (I think) the same problem using ESPUI and ESP32 AsyncElegantOTA.
Changed one line for OTA to: AsyncWebServer server(8080);
ESPUI uses normal port 80
update OTA via: ip-address:8080/update
Works fine, not sure if this solves the problem of @robvoi

I really like the solutions provided here, I do not think I will add OTA into ESPUI, its better if you combine it with external projects for that :-) Pinning this issue as further reference