Compare commits
	
		
			37 Commits
		
	
	
		
			v1.2.61
			...
			e140f8e003
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e140f8e003 | |||
| 3d0bdde476 | |||
| 3ac7d6b4f7 | |||
| 5f52775984 | |||
| 463eaf4b6f | |||
| 4bf6b11d3a | |||
| b0c4af7c4e | |||
| 249e896ea4 | |||
| c74f587fff | |||
| 7a7ee72585 | |||
| 3dd5fbc585 | |||
| ed9c1487ed | |||
| d8756421a1 | |||
| d92c78f9d0 | |||
| 2d19ea745f | |||
| 13779cc9d7 | |||
| b6d5a8a00b | |||
| f6319e79f0 | |||
| 6f24630a7d | |||
| 4475d21218 | |||
| 01a926a38d | |||
| 6b966c02b3 | |||
| 1450e1ad2e | |||
| 3102a6c217 | |||
| d5b2b2746d | |||
| 7e776d4816 | |||
| e84b2973c5 | |||
| 5793dc1a1f | |||
| 1732491c48 | |||
| 0500bb6951 | |||
| ef9ef7257a | |||
| e86fd229dc | |||
| b940a166da | |||
| c857e16de2 | |||
| 8b2a537b72 | |||
| 88ec151c4c | |||
| 0a203f02eb | 
							
								
								
									
										92
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,5 +1,97 @@ | ||||
| # Changelog | ||||
|  | ||||
| ## [1.2.73] - 2025-02-20 | ||||
| ### Changed | ||||
| - update webpages for version v1.2.73 | ||||
| - improve OTA update process with enhanced size checks and progress logging | ||||
|  | ||||
| ### Fixed | ||||
| - enhance OTA update process with improved size checks and debugging output | ||||
|  | ||||
|  | ||||
| ## [1.2.72] - 2025-02-20 | ||||
| ### Changed | ||||
| - update webpages for version v1.2.72 | ||||
| - simplify OTA update process by removing unnecessary buffer and adjusting offsets | ||||
|  | ||||
|  | ||||
| ## [1.2.71] - 2025-02-20 | ||||
| ### Added | ||||
| - update version number to v1.2.65 in HTML files and platformio.ini; add script to create full binary | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version v1.2.71 | ||||
|  | ||||
|  | ||||
| ## [1.2.70] - 2025-02-20 | ||||
| ### Added | ||||
| - add logging to stopAllTasks for better debugging | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version v1.2.70 | ||||
|  | ||||
|  | ||||
| ## [1.2.69] - 2025-02-20 | ||||
| ### Changed | ||||
| - update webpages for version v1.2.69 | ||||
|  | ||||
|  | ||||
| ## [1.2.68] - 2025-02-20 | ||||
| ### Added | ||||
| - add task handles for BambuMqttTask and ScaleTask; rename stopTasks to stopAllTasks | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version v1.2.68 | ||||
|  | ||||
| ### Fixed | ||||
| - update stopAllTasks to suspend RfidReaderTask instead of NfcTask | ||||
|  | ||||
|  | ||||
| ## [1.2.67] - 2025-02-20 | ||||
| ### Added | ||||
| - improve OTA upload handling and add SPIFFS update support | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version v1.2.67 | ||||
|  | ||||
|  | ||||
| ## [1.2.66] - 2025-02-20 | ||||
| ### Added | ||||
| - enhance OTA upload to support SPIFFS updates | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version v1.2.66 | ||||
|  | ||||
|  | ||||
| ## [1.2.65] - 2025-02-20 | ||||
| ### Changed | ||||
| - update webpages for version v1.2.65 | ||||
|  | ||||
|  | ||||
| ## [1.2.64] - 2025-02-20 | ||||
| ### Changed | ||||
| - update webpages for version v1.2.64 | ||||
|  | ||||
| ### Fixed | ||||
| - improve error handling in OTA upload process | ||||
|  | ||||
|  | ||||
| ## [1.2.63] - 2025-02-20 | ||||
| ### Added | ||||
| - update version to 1.2.63 | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version v1.2.63 | ||||
|  | ||||
|  | ||||
| ## [1.2.62] - 2025-02-20 | ||||
| ### Added | ||||
| - update version to 1.2.62 | ||||
|  | ||||
| ### Changed | ||||
| - update webpages for version 1.2.62 | ||||
|  | ||||
|  | ||||
| ## [1.2.61] - 2025-02-20 | ||||
| ### Added | ||||
| - update version to 1.2.61 and enhance OTA update error handling | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||
|             <div class="logo-text"> | ||||
|                 <h1>FilaMan<span class="version">v1.2.61</span></h1> | ||||
|                 <h1>FilaMan<span class="version">v1.2.73</span></h1> | ||||
|                 <h4>Filament Management Tool</h4> | ||||
|             </div> | ||||
|         </div> | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| ; https://docs.platformio.org/page/projectconf.html | ||||
|  | ||||
| [common] | ||||
| version = "1.2.61" | ||||
| version = "1.2.73" | ||||
|  | ||||
| [env:esp32dev] | ||||
| platform = espressif32 | ||||
| @@ -66,6 +66,7 @@ extra_scripts = | ||||
|     pre:scripts/pre_spiffs.py    ; wird als zweites ausgeführt | ||||
|     pre:scripts/combine_html.py  ; wird als drittes ausgeführt | ||||
|     scripts/gzip_files.py | ||||
|     # scripts/create_full_bin.py  # Nicht mehr benötigt, da full.bin im Workflow erstellt wird | ||||
|  | ||||
| ; Remove or comment out the targets line | ||||
| ;targets = buildfs, build | ||||
|   | ||||
							
								
								
									
										48
									
								
								scripts/create_full_bin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								scripts/create_full_bin.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| import os | ||||
| import shutil | ||||
| from platformio import util | ||||
|  | ||||
| Import("env") | ||||
|  | ||||
| def create_full_bin(source, target, env): | ||||
|     # Get paths | ||||
|     firmware_path = str(target[0]) | ||||
|     build_dir = os.path.dirname(firmware_path) | ||||
|     project_dir = env.get("PROJECT_DIR") | ||||
|      | ||||
|     # Create full binary | ||||
|     firmware_name = os.path.basename(firmware_path) | ||||
|     spiffs_bin = os.path.join(build_dir, "spiffs.bin") | ||||
|     full_bin = os.path.join(build_dir, "full.bin") | ||||
|      | ||||
|     print("Creating full.bin...") | ||||
|      | ||||
|     # Check if files exist | ||||
|     if not os.path.exists(firmware_path): | ||||
|         print("Error: Firmware binary not found!") | ||||
|         return | ||||
|     if not os.path.exists(spiffs_bin): | ||||
|         print("Error: SPIFFS binary not found!") | ||||
|         return | ||||
|      | ||||
|     # Calculate padding size | ||||
|     firmware_size = os.path.getsize(firmware_path) | ||||
|     padding_size = 0x3D0000 - firmware_size  # SPIFFS start address - firmware size | ||||
|      | ||||
|     # Create full binary | ||||
|     with open(full_bin, 'wb') as outfile: | ||||
|         # Copy firmware | ||||
|         with open(firmware_path, 'rb') as f: | ||||
|             outfile.write(f.read()) | ||||
|          | ||||
|         # Add padding | ||||
|         outfile.write(b'\xFF' * padding_size) | ||||
|          | ||||
|         # Copy SPIFFS | ||||
|         with open(spiffs_bin, 'rb') as f: | ||||
|             outfile.write(f.read()) | ||||
|      | ||||
|     print(f"Created full.bin ({os.path.getsize(full_bin)} bytes)") | ||||
|  | ||||
| # Register the callback | ||||
| env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", create_full_bin) | ||||
| @@ -36,4 +36,5 @@ void mqtt_loop(void * parameter); | ||||
| bool setBambuSpool(String payload); | ||||
| void bambu_restart(); | ||||
|  | ||||
| extern TaskHandle_t BambuMqttTask; | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										120
									
								
								src/ota.cpp
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								src/ota.cpp
									
									
									
									
									
								
							| @@ -3,59 +3,121 @@ | ||||
| #include <Update.h> | ||||
| #include <SPIFFS.h> | ||||
| #include "commonFS.h" | ||||
| #include "bambu.h" | ||||
| #include "scale.h" | ||||
| #include "nfc.h" | ||||
|  | ||||
| // Magic byte patterns für verschiedene Image-Typen | ||||
| const uint8_t FIRMWARE_MAGIC = 0xE9; | ||||
| const uint8_t ESP_MAGIC = 0xE9; | ||||
| static bool tasksAreStopped = false; | ||||
|  | ||||
| void stopAllTasks() { | ||||
|     // Stop all tasks | ||||
|     Serial.println("Stopping RFID Reader"); | ||||
|     if (RfidReaderTask) vTaskSuspend(RfidReaderTask); | ||||
|     Serial.println("Stopping Bambu"); | ||||
|     if (BambuMqttTask) vTaskSuspend(BambuMqttTask); | ||||
|     Serial.println("Stopping Scale"); | ||||
|     if (ScaleTask) vTaskSuspend(ScaleTask); | ||||
|     vTaskDelay(100 / portTICK_PERIOD_MS); | ||||
|     Serial.println("All tasks stopped"); | ||||
| } | ||||
|  | ||||
| void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { | ||||
|     static size_t contentLength = 0; | ||||
|     static bool isFullImage = false; | ||||
|     static uint32_t currentOffset = 0; | ||||
|      | ||||
|     // Flash layout constants from partitions.csv | ||||
|     static const uint32_t FLASH_SIZE = 0x400000;    // 4MB total | ||||
|     static const uint32_t APP_SIZE = 0x1E0000;      // Size per app partition | ||||
|     static const uint32_t SPIFFS_OFFSET = 0x3D0000; // SPIFFS start | ||||
|      | ||||
|     if (!index) { | ||||
|         contentLength = request->contentLength(); | ||||
|         Serial.printf("Update size: %u bytes\n", contentLength); | ||||
|         Serial.printf("Update size: %u bytes (0x%X)\n", contentLength, contentLength); | ||||
|          | ||||
|         if (contentLength == 0) { | ||||
|             request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Invalid file size\"}"); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Determine if this is a full image (firmware + SPIFFS) or just firmware | ||||
|         bool isFullImage = (contentLength > 0x3D0000); // SPIFFS starts at 0x3D0000 | ||||
|  | ||||
|         if (isFullImage) { | ||||
|             // For full images, we need to make sure we have enough space and properly partition it | ||||
|             if (!Update.begin(ESP.getFreeSketchSpace(), U_FLASH)) { | ||||
|                 Serial.printf("Not enough space for full image: %u bytes required\n", contentLength); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Full image updates are not supported via OTA. Please use USB update for full images.\"}"); | ||||
|                 return; | ||||
|             } | ||||
|         } else { | ||||
|             // For firmware-only updates | ||||
|             if (!Update.begin(contentLength, U_FLASH)) { | ||||
|                 Serial.printf("Not enough space: %u required\n", contentLength); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Not enough space available for firmware update\"}"); | ||||
|                 return; | ||||
|             } | ||||
|         if (!tasksAreStopped && (RfidReaderTask || BambuMqttTask || ScaleTask)) { | ||||
|             stopAllTasks(); | ||||
|             tasksAreStopped = true; | ||||
|         } | ||||
|  | ||||
|         isFullImage = (contentLength >= SPIFFS_OFFSET); | ||||
|          | ||||
|         Serial.println(isFullImage ? "Full image update started" : "Firmware update started"); | ||||
|         if (!isFullImage) { | ||||
|             // Regular firmware update must not exceed app partition size | ||||
|             if (contentLength > APP_SIZE) { | ||||
|                 Serial.printf("Firmware too large: 0x%X > 0x%X\n", contentLength, APP_SIZE); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Firmware too large\"}"); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             if (!Update.begin(contentLength)) { | ||||
|                 Serial.printf("Not enough space for firmware: %u required\n", contentLength); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Not enough space available\"}"); | ||||
|                 return; | ||||
|             } | ||||
|             Serial.printf("Firmware update started (size: 0x%X)\n", contentLength); | ||||
|         } else { | ||||
|             // Full image update | ||||
|             if (contentLength > FLASH_SIZE) { | ||||
|                 Serial.printf("Image too large: 0x%X > 0x%X\n", contentLength, FLASH_SIZE); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Image too large\"}"); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|             if (!Update.begin(FLASH_SIZE, U_FLASH)) { | ||||
|                 Serial.println("Could not begin full image update"); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Could not start full update\"}"); | ||||
|                 return; | ||||
|             } | ||||
|             Serial.printf("Full image update started (size: 0x%X)\n", contentLength); | ||||
|         } | ||||
|         currentOffset = 0; | ||||
|     } | ||||
|  | ||||
|     if (Update.write(data, len) != len) { | ||||
|         String errorMsg = Update.errorString(); | ||||
|         if (errorMsg != "No Error") { | ||||
|             Update.printError(Serial); | ||||
|             Serial.printf("Error at offset: 0x%X of 0x%X bytes\n", currentOffset, contentLength); | ||||
|             request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Error writing update: " + errorMsg + "\"}"); | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     // Write chunk to flash | ||||
|     if (Update.write(data, len) != len) { | ||||
|         Update.printError(Serial); | ||||
|         String errorMsg = Update.errorString(); | ||||
|         request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Error writing update: " + errorMsg + "\"}"); | ||||
|         return; | ||||
|     // Progress logging | ||||
|     if ((currentOffset % 0x40000) == 0) { // Log every 256KB | ||||
|         Serial.printf("Update progress: 0x%X of 0x%X bytes (%.1f%%)\n",  | ||||
|             currentOffset,  | ||||
|             contentLength,  | ||||
|             (currentOffset * 100.0) / contentLength); | ||||
|     } | ||||
|  | ||||
|      | ||||
|     currentOffset += len; | ||||
|      | ||||
|     if (final) { | ||||
|         if (Update.end(true)) { | ||||
|             Serial.println("Update complete"); | ||||
|             Serial.printf("Update complete: 0x%X bytes written\n", currentOffset); | ||||
|             request->send(200, "application/json", "{\"status\":\"success\",\"message\":\"Update successful! Device will restart...\",\"restart\":true}"); | ||||
|             delay(1000); | ||||
|             ESP.restart(); | ||||
|         } else { | ||||
|             String errorMsg = Update.errorString(); | ||||
|             Update.printError(Serial); | ||||
|             request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Update failed: " + errorMsg + "\"}"); | ||||
|             if (errorMsg != "No Error") { | ||||
|                 Update.printError(Serial); | ||||
|                 request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Update failed: " + errorMsg + "\"}"); | ||||
|             } else { | ||||
|                 request->send(200, "application/json", "{\"status\":\"success\",\"message\":\"Update successful! Device will restart...\",\"restart\":true}"); | ||||
|                 delay(1000); | ||||
|                 ESP.restart(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,12 @@ | ||||
|  | ||||
| #include <ESPAsyncWebServer.h> | ||||
|  | ||||
| // Update size unknown constant, falls nicht bereits definiert | ||||
| #ifndef UPDATE_SIZE_UNKNOWN | ||||
| #define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF | ||||
| #endif | ||||
|  | ||||
| void stopAllTasks(); | ||||
| void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final); | ||||
|  | ||||
| #endif | ||||
| @@ -15,4 +15,6 @@ extern uint8_t weigthCouterToApi; | ||||
| extern uint8_t scale_tare_counter; | ||||
| extern uint8_t pauseMainTask; | ||||
|  | ||||
| extern TaskHandle_t ScaleTask; | ||||
|  | ||||
| #endif | ||||
| @@ -12,7 +12,7 @@ bool wm_nonblocking = false; | ||||
| void initWiFi() { | ||||
|     WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP | ||||
|    | ||||
|     esp_wifi_set_max_tx_power(72); // Setze maximale Sendeleistung auf 20dBm | ||||
|     //esp_wifi_set_max_tx_power(72); // Setze maximale Sendeleistung auf 20dBm | ||||
|    | ||||
|     if(wm_nonblocking) wm.setConfigPortalBlocking(false); | ||||
|     wm.setConfigPortalTimeout(320); // Portal nach 5min schließen | ||||
|   | ||||
		Reference in New Issue
	
	Block a user