feat: update version to 1.2.2; change OTA upgrade link in HTML files; enhance OTA upload handling with progress updates and JSON responses
This commit is contained in:
		
							
								
								
									
										23
									
								
								src/ota.cpp
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								src/ota.cpp
									
									
									
									
									
								
							@@ -127,10 +127,12 @@ bool restoreConfigs() {
 | 
			
		||||
void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
 | 
			
		||||
    static bool updateStarted = false;
 | 
			
		||||
    static size_t totalBytes = 0;
 | 
			
		||||
    static size_t totalSize = 0;
 | 
			
		||||
 | 
			
		||||
    if (!index) {
 | 
			
		||||
        updateStarted = false;
 | 
			
		||||
        totalBytes = 0;
 | 
			
		||||
        totalSize = request->contentLength();
 | 
			
		||||
 | 
			
		||||
        // Check minimum heap size
 | 
			
		||||
        if (ESP.getFreeHeap() < MIN_FREE_HEAP) {
 | 
			
		||||
@@ -138,13 +140,12 @@ void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t ind
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        size_t updateSize = request->contentLength();
 | 
			
		||||
        if (updateSize == 0) {
 | 
			
		||||
        if (totalSize == 0) {
 | 
			
		||||
            request->send(400, "text/plain", "Invalid file size");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Serial.printf("Update size: %u bytes\n", updateSize);
 | 
			
		||||
        Serial.printf("Update size: %u bytes\n", totalSize);
 | 
			
		||||
        Serial.printf("Free space: %u bytes\n", ESP.getFreeSketchSpace());
 | 
			
		||||
        Serial.printf("Free heap: %u bytes\n", ESP.getFreeHeap());
 | 
			
		||||
 | 
			
		||||
@@ -158,7 +159,7 @@ void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t ind
 | 
			
		||||
        SPIFFS.end();
 | 
			
		||||
 | 
			
		||||
        // Begin update with minimal configuration
 | 
			
		||||
        if (!Update.begin(updateSize)) {
 | 
			
		||||
        if (!Update.begin(totalSize)) {
 | 
			
		||||
            Serial.printf("Update.begin failed: %s\n", Update.errorString());
 | 
			
		||||
            request->send(500, "text/plain", "Failed to start update");
 | 
			
		||||
            return;
 | 
			
		||||
@@ -166,6 +167,9 @@ void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t ind
 | 
			
		||||
 | 
			
		||||
        updateStarted = true;
 | 
			
		||||
        Serial.println("Update process started");
 | 
			
		||||
        
 | 
			
		||||
        // Send initial progress
 | 
			
		||||
        request->send(200, "text/plain", "0");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!updateStarted) {
 | 
			
		||||
@@ -182,8 +186,11 @@ void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t ind
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    totalBytes += len;
 | 
			
		||||
    if (totalBytes % (32 * 1024) == 0) {
 | 
			
		||||
        Serial.printf("Progress: %u bytes\n", totalBytes);
 | 
			
		||||
    
 | 
			
		||||
    // Send progress update
 | 
			
		||||
    if (!final) {
 | 
			
		||||
        int progress = (totalBytes * 100) / totalSize;
 | 
			
		||||
        request->send(200, "text/plain", String(progress));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (final) {
 | 
			
		||||
@@ -196,7 +203,7 @@ void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t ind
 | 
			
		||||
        // Try to restore configs
 | 
			
		||||
        if (!SPIFFS.begin(true)) {
 | 
			
		||||
            Serial.println("Failed to mount SPIFFS for restore");
 | 
			
		||||
            request->send(200, "text/plain", "Update successful but config restore failed. Device will restart...");
 | 
			
		||||
            request->send(200, "application/json", "{\"status\": \"success\", \"message\": \"Update successful but config restore failed. Device will restart...\", \"restart\": true}");
 | 
			
		||||
            delay(2000);
 | 
			
		||||
            ESP.restart();
 | 
			
		||||
            return;
 | 
			
		||||
@@ -206,7 +213,7 @@ void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t ind
 | 
			
		||||
            Serial.println("Failed to restore configs");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        request->send(200, "text/plain", "Update successful. Device will restart...");
 | 
			
		||||
        request->send(200, "application/json", "{\"status\": \"success\", \"message\": \"Update successful! Device will restart...\", \"restart\": true}");
 | 
			
		||||
        delay(2000);
 | 
			
		||||
        ESP.restart();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								src/website.cpp
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								src/website.cpp
									
									
									
									
									
								
							@@ -338,101 +338,12 @@ void setupWebserver(AsyncWebServer &server) {
 | 
			
		||||
        Serial.println("RFID.js gesendet");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Route für OTA Updates
 | 
			
		||||
    server.on("/ota", HTTP_GET, [](AsyncWebServerRequest *request) {
 | 
			
		||||
        Serial.println("Anfrage für /ota erhalten");
 | 
			
		||||
        
 | 
			
		||||
        String html = R"(
 | 
			
		||||
            <!DOCTYPE html>
 | 
			
		||||
            <html>
 | 
			
		||||
            <head>
 | 
			
		||||
                <title>Firmware Update</title>
 | 
			
		||||
                <link rel="stylesheet" type="text/css" href="/style.css">
 | 
			
		||||
                <style>
 | 
			
		||||
                    .progress-container {
 | 
			
		||||
                        width: 100%;
 | 
			
		||||
                        margin: 20px 0;
 | 
			
		||||
                        display: none;
 | 
			
		||||
                    }
 | 
			
		||||
                    .progress-bar {
 | 
			
		||||
                        width: 0%;
 | 
			
		||||
                        height: 20px;
 | 
			
		||||
                        background-color: #4CAF50;
 | 
			
		||||
                        text-align: center;
 | 
			
		||||
                        line-height: 20px;
 | 
			
		||||
                        color: white;
 | 
			
		||||
                    }
 | 
			
		||||
                    .status {
 | 
			
		||||
                        margin: 10px 0;
 | 
			
		||||
                        padding: 10px;
 | 
			
		||||
                        display: none;
 | 
			
		||||
                    }
 | 
			
		||||
                    .error { background-color: #ffebee; color: #c62828; }
 | 
			
		||||
                    .success { background-color: #e8f5e9; color: #2e7d32; }
 | 
			
		||||
                </style>
 | 
			
		||||
            </head>
 | 
			
		||||
            <body>
 | 
			
		||||
                <h2>Firmware Update</h2>
 | 
			
		||||
                <form id="updateForm" enctype='multipart/form-data'>
 | 
			
		||||
                    <input type='file' name='update' accept='.bin' required>
 | 
			
		||||
                    <input type='submit' value='Update Firmware'>
 | 
			
		||||
                </form>
 | 
			
		||||
                <div class="progress-container">
 | 
			
		||||
                    <div class="progress-bar">0%</div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="status"></div>
 | 
			
		||||
                <script>
 | 
			
		||||
                    document.getElementById('updateForm').addEventListener('submit', async (e) => {
 | 
			
		||||
                        e.preventDefault();
 | 
			
		||||
                        const form = e.target;
 | 
			
		||||
                        const file = form.update.files[0];
 | 
			
		||||
                        const formData = new FormData();
 | 
			
		||||
                        formData.append('update', file);
 | 
			
		||||
 | 
			
		||||
                        const progress = document.querySelector('.progress-bar');
 | 
			
		||||
                        const progressContainer = document.querySelector('.progress-container');
 | 
			
		||||
                        const status = document.querySelector('.status');
 | 
			
		||||
                        
 | 
			
		||||
                        progressContainer.style.display = 'block';
 | 
			
		||||
                        status.style.display = 'none';
 | 
			
		||||
                        status.className = 'status';
 | 
			
		||||
                        form.querySelector('input[type=submit]').disabled = true;
 | 
			
		||||
 | 
			
		||||
                        try {
 | 
			
		||||
                            const response = await fetch('/update', {
 | 
			
		||||
                                method: 'POST',
 | 
			
		||||
                                body: formData,
 | 
			
		||||
                                onUploadProgress: (e) => {
 | 
			
		||||
                                    const percent = (e.loaded / e.total) * 100;
 | 
			
		||||
                                    progress.style.width = percent + '%';
 | 
			
		||||
                                    progress.textContent = Math.round(percent) + '%';
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
 | 
			
		||||
                            const result = await response.text();
 | 
			
		||||
                            status.textContent = result;
 | 
			
		||||
                            status.classList.add(response.ok ? 'success' : 'error');
 | 
			
		||||
                            status.style.display = 'block';
 | 
			
		||||
 | 
			
		||||
                            if (response.ok) {
 | 
			
		||||
                                setTimeout(() => {
 | 
			
		||||
                                    window.location.reload();
 | 
			
		||||
                                }, 5000);
 | 
			
		||||
                            } else {
 | 
			
		||||
                                form.querySelector('input[type=submit]').disabled = false;
 | 
			
		||||
                            }
 | 
			
		||||
                        } catch (error) {
 | 
			
		||||
                            status.textContent = 'Update failed: ' + error.message;
 | 
			
		||||
                            status.classList.add('error');
 | 
			
		||||
                            status.style.display = 'block';
 | 
			
		||||
                            form.querySelector('input[type=submit]').disabled = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                </script>
 | 
			
		||||
            </body>
 | 
			
		||||
            </html>
 | 
			
		||||
        )";
 | 
			
		||||
        request->send(200, "text/html", html);
 | 
			
		||||
    // Route für Firmware Update
 | 
			
		||||
    server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest *request) {
 | 
			
		||||
        AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/upgrade.html.gz", "text/html");
 | 
			
		||||
        response->addHeader("Content-Encoding", "gzip");
 | 
			
		||||
        response->addHeader("Cache-Control", CACHE_CONTROL);
 | 
			
		||||
        request->send(response);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    server.on("/update", HTTP_POST, 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user