Compare commits
	
		
			9 Commits
		
	
	
		
			v1.2.2
			...
			b13f2c4eee
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b13f2c4eee | |||
| 6d16c35e62 | |||
| c94ebf5e33 | |||
| 9203706a20 | |||
| c252f48a49 | |||
| 228dcacb1e | |||
| 9de4ed9ee9 | |||
| 4d8a6fb943 | |||
| 2cab24403e | 
							
								
								
									
										103
									
								
								.github/workflows/providers/gitea-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								.github/workflows/providers/gitea-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | |||||||
|  | name: Gitea Release | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     tags: | ||||||
|  |       - 'v*' | ||||||
|  |  | ||||||
|  | permissions: | ||||||
|  |   contents: write      # Required for creating releases | ||||||
|  |   issues: read        # Required for reading changelog | ||||||
|  |   pull-requests: read # Required for reading changelog | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     permissions: | ||||||
|  |       contents: write | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v4 | ||||||
|  |      | ||||||
|  |     - name: Set up Python | ||||||
|  |       uses: actions/setup-python@v4 | ||||||
|  |       with: | ||||||
|  |         python-version: '3.x' | ||||||
|  |      | ||||||
|  |     - name: Install PlatformIO | ||||||
|  |       run: | | ||||||
|  |         python -m pip install --upgrade pip | ||||||
|  |         pip install --upgrade platformio | ||||||
|  |      | ||||||
|  |     - name: Build Firmware | ||||||
|  |       run: | | ||||||
|  |         pio run -t buildfs  # Build SPIFFS | ||||||
|  |         pio run            # Build firmware | ||||||
|  |          | ||||||
|  |     - name: Install esptool | ||||||
|  |       run: | | ||||||
|  |         pip install esptool | ||||||
|  |          | ||||||
|  |     - name: Merge firmware and SPIFFS | ||||||
|  |       run: | | ||||||
|  |         esptool.py --chip esp32 merge_bin \ | ||||||
|  |           --flash_mode dio \ | ||||||
|  |           --flash_freq 40m \ | ||||||
|  |           --flash_size 4MB \ | ||||||
|  |           -o .pio/build/esp32dev/filaman_full.bin \ | ||||||
|  |           0x1000 .pio/build/esp32dev/bootloader.bin \ | ||||||
|  |           0x8000 .pio/build/esp32dev/partitions.bin \ | ||||||
|  |           0x10000 .pio/build/esp32dev/firmware.bin \ | ||||||
|  |           0x290000 .pio/build/esp32dev/spiffs.bin | ||||||
|  |  | ||||||
|  |     - name: Prepare OTA firmware | ||||||
|  |       run: | | ||||||
|  |         cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/filaman_ota.bin | ||||||
|  |      | ||||||
|  |     - name: Get version from tag | ||||||
|  |       id: get_version | ||||||
|  |       run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT | ||||||
|  |        | ||||||
|  |     - name: Read CHANGELOG.md | ||||||
|  |       id: changelog | ||||||
|  |       run: | | ||||||
|  |         CHANGELOG=$(awk "/## \\[${{ steps.get_version.outputs.VERSION }}\\]/{p=1;print;next} /## \\[/{p=0} p" CHANGELOG.md) | ||||||
|  |         echo "CHANGES<<EOF" >> $GITHUB_OUTPUT | ||||||
|  |         echo "$CHANGELOG" >> $GITHUB_OUTPUT | ||||||
|  |         echo "EOF" >> $GITHUB_OUTPUT | ||||||
|  |      | ||||||
|  |     - name: Create Release | ||||||
|  |     env: | ||||||
|  |         GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} | ||||||
|  |         GITEA_API_URL: ${{ secrets.GITEA_API_URL }} | ||||||
|  |         GITEA_REPOSITORY: ${{ secrets.GITEA_REPOSITORY }} | ||||||
|  |     run: | | ||||||
|  |         # Create release using Gitea API | ||||||
|  |         RESPONSE=$(curl -X POST \ | ||||||
|  |         -H "Authorization: token ${GITEA_TOKEN}" \ | ||||||
|  |         -H "Content-Type: application/json" \ | ||||||
|  |         -H "accept: application/json" \ | ||||||
|  |         "${GITEA_API_URL}/repos/${GITEA_REPOSITORY}/releases" \ | ||||||
|  |         -d '{ | ||||||
|  |             "tag_name": "${{ github.ref_name }}", | ||||||
|  |             "name": "Release ${{ steps.get_version.outputs.VERSION }}", | ||||||
|  |             "body": "${{ steps.changelog.outputs.CHANGES }}", | ||||||
|  |             "draft": false, | ||||||
|  |             "prerelease": false | ||||||
|  |         }') | ||||||
|  |          | ||||||
|  |         # Extract release ID from response | ||||||
|  |         RELEASE_ID=$(echo $RESPONSE | jq -r .id) | ||||||
|  |          | ||||||
|  |         # Upload full firmware | ||||||
|  |         curl -X POST \ | ||||||
|  |         -H "Authorization: token ${GITEA_TOKEN}" \ | ||||||
|  |         -H "Content-Type: application/octet-stream" \ | ||||||
|  |         "${GITEA_API_URL}/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets?name=filaman_full.bin" \ | ||||||
|  |         --data-binary @.pio/build/esp32dev/filaman_full.bin | ||||||
|  |          | ||||||
|  |         # Upload OTA firmware | ||||||
|  |         curl -X POST \ | ||||||
|  |         -H "Authorization: token ${GITEA_TOKEN}" \ | ||||||
|  |         -H "Content-Type: application/octet-stream" \ | ||||||
|  |         "${GITEA_API_URL}/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets?name=filaman_ota.bin" \ | ||||||
|  |         --data-binary @.pio/build/esp32dev/filaman_ota.bin | ||||||
							
								
								
									
										85
									
								
								.github/workflows/providers/github-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								.github/workflows/providers/github-release.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | |||||||
|  | name: GitHub Release | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     tags: | ||||||
|  |       - 'v*' | ||||||
|  |  | ||||||
|  | permissions: | ||||||
|  |   contents: write      # Required for creating releases | ||||||
|  |   issues: read        # Required for reading changelog | ||||||
|  |   pull-requests: read # Required for reading changelog | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     permissions: | ||||||
|  |       contents: write # Required for creating releases at job level | ||||||
|  |     steps: | ||||||
|  |     - uses: actions/checkout@v4 | ||||||
|  |      | ||||||
|  |     - name: Set up Python | ||||||
|  |       uses: actions/setup-python@v4 | ||||||
|  |       with: | ||||||
|  |         python-version: '3.x' | ||||||
|  |      | ||||||
|  |     - name: Install PlatformIO | ||||||
|  |       run: | | ||||||
|  |         python -m pip install --upgrade pip | ||||||
|  |         pip install --upgrade platformio | ||||||
|  |      | ||||||
|  |     - name: Build Firmware | ||||||
|  |       run: | | ||||||
|  |         pio run -t buildfs  # Build SPIFFS | ||||||
|  |         pio run            # Build firmware | ||||||
|  |          | ||||||
|  |     - name: Install esptool | ||||||
|  |       run: | | ||||||
|  |         pip install esptool | ||||||
|  |          | ||||||
|  |     - name: Merge firmware and SPIFFS | ||||||
|  |       run: | | ||||||
|  |         esptool.py --chip esp32 merge_bin \ | ||||||
|  |           --flash_mode dio \ | ||||||
|  |           --flash_freq 40m \ | ||||||
|  |           --flash_size 4MB \ | ||||||
|  |           -o .pio/build/esp32dev/filaman_full.bin \ | ||||||
|  |           0x1000 .pio/build/esp32dev/bootloader.bin \ | ||||||
|  |           0x8000 .pio/build/esp32dev/partitions.bin \ | ||||||
|  |           0x10000 .pio/build/esp32dev/firmware.bin \ | ||||||
|  |           0x290000 .pio/build/esp32dev/spiffs.bin | ||||||
|  |  | ||||||
|  |     - name: Prepare OTA firmware | ||||||
|  |       run: | | ||||||
|  |         # Use PlatformIO to create a proper OTA image | ||||||
|  |         cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/filaman_ota.bin | ||||||
|  |      | ||||||
|  |     - name: Get version from tag | ||||||
|  |       id: get_version | ||||||
|  |       run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT | ||||||
|  |        | ||||||
|  |     - name: Read CHANGELOG.md | ||||||
|  |       id: changelog | ||||||
|  |       run: | | ||||||
|  |         CHANGELOG=$(awk "/## \\[${{ steps.get_version.outputs.VERSION }}\\]/{p=1;print;next} /## \\[/{p=0} p" CHANGELOG.md) | ||||||
|  |         echo "CHANGES<<EOF" >> $GITHUB_OUTPUT | ||||||
|  |         echo "$CHANGELOG" >> $GITHUB_OUTPUT | ||||||
|  |         echo "EOF" >> $GITHUB_OUTPUT | ||||||
|  |      | ||||||
|  |     - name: Install and Configure GitHub CLI | ||||||
|  |       run: | | ||||||
|  |         curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ | ||||||
|  |         && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ | ||||||
|  |         && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ | ||||||
|  |         && sudo apt update \ | ||||||
|  |         && sudo apt install gh -y | ||||||
|  |          | ||||||
|  |     - name: Create Release with GitHub CLI | ||||||
|  |       env: | ||||||
|  |         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |       run: | | ||||||
|  |         gh release create "${{ github.ref_name }}" \ | ||||||
|  |           --title "Release ${{ steps.get_version.outputs.VERSION }}" \ | ||||||
|  |           --notes "${{ steps.changelog.outputs.CHANGES }}" \ | ||||||
|  |           ".pio/build/esp32dev/filaman_full.bin#filaman_full.bin" \ | ||||||
|  |           ".pio/build/esp32dev/filaman_ota.bin#filaman_ota.bin" | ||||||
							
								
								
									
										95
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										95
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,85 +1,30 @@ | |||||||
| name: Create Release | name: Release | ||||||
|  |  | ||||||
| on: | on: | ||||||
|   push: |   push: | ||||||
|     tags: |     tags: | ||||||
|       - 'v*' |       - 'v*' | ||||||
|  |  | ||||||
| permissions: |  | ||||||
|   contents: write      # Required for creating releases |  | ||||||
|   issues: read        # Required for reading changelog |  | ||||||
|   pull-requests: read # Required for reading changelog |  | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   build: |   detect-and-run: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     permissions: |  | ||||||
|       contents: write # Required for creating releases at job level |  | ||||||
|     steps: |     steps: | ||||||
|     - uses: actions/checkout@v4 |       - name: Checkout code | ||||||
|      |         uses: actions/checkout@v4 | ||||||
|     - name: Set up Python |  | ||||||
|       uses: actions/setup-python@v4 |  | ||||||
|       with: |  | ||||||
|         python-version: '3.x' |  | ||||||
|      |  | ||||||
|     - name: Install PlatformIO |  | ||||||
|       run: | |  | ||||||
|         python -m pip install --upgrade pip |  | ||||||
|         pip install --upgrade platformio |  | ||||||
|      |  | ||||||
|     - name: Build Firmware |  | ||||||
|       run: | |  | ||||||
|         pio run -t buildfs  # Build SPIFFS |  | ||||||
|         pio run            # Build firmware |  | ||||||
|          |  | ||||||
|     - name: Install esptool |  | ||||||
|       run: | |  | ||||||
|         pip install esptool |  | ||||||
|          |  | ||||||
|     - name: Merge firmware and SPIFFS |  | ||||||
|       run: | |  | ||||||
|         esptool.py --chip esp32 merge_bin \ |  | ||||||
|           --flash_mode dio \ |  | ||||||
|           --flash_freq 40m \ |  | ||||||
|           --flash_size 4MB \ |  | ||||||
|           -o .pio/build/esp32dev/filaman_full.bin \ |  | ||||||
|           0x1000 .pio/build/esp32dev/bootloader.bin \ |  | ||||||
|           0x8000 .pio/build/esp32dev/partitions.bin \ |  | ||||||
|           0x10000 .pio/build/esp32dev/firmware.bin \ |  | ||||||
|           0x290000 .pio/build/esp32dev/spiffs.bin |  | ||||||
|  |  | ||||||
|     - name: Prepare OTA firmware |       - name: Determine hosting platform | ||||||
|       run: | |         id: platform | ||||||
|         # Use PlatformIO to create a proper OTA image |         run: | | ||||||
|         cp .pio/build/esp32dev/firmware.bin .pio/build/esp32dev/filaman_ota.bin |           if [[ "$GITHUB_SERVER_URL" == "https://github.com" ]]; then | ||||||
|      |             echo "platform=github" >> $GITHUB_OUTPUT | ||||||
|     - name: Get version from tag |           else | ||||||
|       id: get_version |             echo "platform=gitea" >> $GITHUB_OUTPUT | ||||||
|       run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT |           fi | ||||||
|        |  | ||||||
|     - name: Read CHANGELOG.md |       - name: Run Release Workflow | ||||||
|       id: changelog |         run: | | ||||||
|       run: | |           if [[ "${{ steps.platform.outputs.platform }}" == "github" ]]; then | ||||||
|         CHANGELOG=$(awk "/## \\[${{ steps.get_version.outputs.VERSION }}\\]/{p=1;print;next} /## \\[/{p=0} p" CHANGELOG.md) |             ./.github/workflows/providers/github-release.sh | ||||||
|         echo "CHANGES<<EOF" >> $GITHUB_OUTPUT |           else | ||||||
|         echo "$CHANGELOG" >> $GITHUB_OUTPUT |             ./.github/workflows/providers/gitea-release.sh | ||||||
|         echo "EOF" >> $GITHUB_OUTPUT |           fi | ||||||
|      |  | ||||||
|     - name: Install and Configure GitHub CLI |  | ||||||
|       run: | |  | ||||||
|         curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \ |  | ||||||
|         && sudo chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \ |  | ||||||
|         && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \ |  | ||||||
|         && sudo apt update \ |  | ||||||
|         && sudo apt install gh -y |  | ||||||
|          |  | ||||||
|     - name: Create Release with GitHub CLI |  | ||||||
|       env: |  | ||||||
|         GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |  | ||||||
|       run: | |  | ||||||
|         gh release create "${{ github.ref_name }}" \ |  | ||||||
|           --title "Release ${{ steps.get_version.outputs.VERSION }}" \ |  | ||||||
|           --notes "${{ steps.changelog.outputs.CHANGES }}" \ |  | ||||||
|           ".pio/build/esp32dev/filaman_full.bin#filaman_full.bin" \ |  | ||||||
|           ".pio/build/esp32dev/filaman_ota.bin#filaman_ota.bin" |  | ||||||
							
								
								
									
										25
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,5 +1,30 @@ | |||||||
| # Changelog | # Changelog | ||||||
|  |  | ||||||
|  | ## [1.2.6] - 2025-02-18 | ||||||
|  | ### Added | ||||||
|  | - update version to 1.2.6 in platformio.ini | ||||||
|  | - update version to 1.2.5; enhance Gitea release workflow and streamline release process | ||||||
|  |  | ||||||
|  | ### Changed | ||||||
|  | - update changelog for version 1.2.5 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## [1.2.5] - 2025-02-18 | ||||||
|  | ### Added | ||||||
|  | - update version to 1.2.5; enhance Gitea release workflow and streamline release process | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## [1.2.4] - 2025-02-18 | ||||||
|  | ### Added | ||||||
|  | - update version to 1.2.4 in HTML files and platformio.ini | ||||||
|  | - add GitHub and Gitea release workflows; streamline firmware release process | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## [1.2.3] - 2025-02-18 | ||||||
|  | ### Added | ||||||
|  | - update version to 1.2.3; modify HTML files to reflect new version; enhance firmware update process and UI improvements | ||||||
|  |  | ||||||
|  |  | ||||||
| ## [1.2.2] - 2025-02-18 | ## [1.2.2] - 2025-02-18 | ||||||
| ### Added | ### Added | ||||||
| - update version to 1.2.2; change OTA upgrade link in HTML files; enhance OTA upload handling with progress updates and JSON responses | - update version to 1.2.2; change OTA upgrade link in HTML files; enhance OTA upload handling with progress updates and JSON responses | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -1056,6 +1056,7 @@ input[type="submit"]:disabled, | |||||||
|     box-shadow: 0 2px 4px rgba(0,0,0,0.1); |     box-shadow: 0 2px 4px rgba(0,0,0,0.1); | ||||||
|     margin: 0 auto; |     margin: 0 auto; | ||||||
|     width: 400px; |     width: 400px; | ||||||
|  |     text-align: center; | ||||||
| } | } | ||||||
| .update-form input[type="file"] { | .update-form input[type="file"] { | ||||||
|     margin-bottom: 15px; |     margin-bottom: 15px; | ||||||
| @@ -1063,6 +1064,7 @@ input[type="submit"]:disabled, | |||||||
|     padding: 8px; |     padding: 8px; | ||||||
|     border: 1px solid #ddd; |     border: 1px solid #ddd; | ||||||
|     border-radius: 4px; |     border-radius: 4px; | ||||||
|  |     background: white; | ||||||
| } | } | ||||||
| .update-form input[type="submit"] { | .update-form input[type="submit"] { | ||||||
|     background-color: #4CAF50; |     background-color: #4CAF50; | ||||||
| @@ -1072,6 +1074,7 @@ input[type="submit"]:disabled, | |||||||
|     border-radius: 4px; |     border-radius: 4px; | ||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|     font-size: 16px; |     font-size: 16px; | ||||||
|  |     transition: background-color 0.3s; | ||||||
| } | } | ||||||
| .update-form input[type="submit"]:hover { | .update-form input[type="submit"]:hover { | ||||||
|     background-color: #45a049; |     background-color: #45a049; | ||||||
| @@ -1083,8 +1086,10 @@ input[type="submit"]:disabled, | |||||||
| .warning { | .warning { | ||||||
|     background-color: var(--primary-color); |     background-color: var(--primary-color); | ||||||
|     border: 1px solid #ffe0b2; |     border: 1px solid #ffe0b2; | ||||||
|     color: #e65100; |     color: white; | ||||||
|     padding: 15px; |     padding: 15px; | ||||||
|     margin: 20px 0; |     margin: 20px auto; | ||||||
|     border-radius: 4px; |     border-radius: 4px; | ||||||
|  |     max-width: 600px; | ||||||
|  |     text-align: center; | ||||||
| } | } | ||||||
| @@ -1,4 +1,3 @@ | |||||||
|  |  | ||||||
| <!-- head --><!DOCTYPE html> | <!-- head --><!DOCTYPE html> | ||||||
| <html lang="en"> | <html lang="en"> | ||||||
| <head> | <head> | ||||||
| @@ -13,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
| @@ -42,14 +41,13 @@ | |||||||
|  |  | ||||||
|         <div class="warning"> |         <div class="warning"> | ||||||
|             <strong>Warning:</strong> Please do not turn off or restart the device during the update.  |             <strong>Warning:</strong> Please do not turn off or restart the device during the update.  | ||||||
|                         Configuration files will be automatically backed up and restored after the update. |             The device will restart automatically after the update. | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
|          |         <div class="update-form"> | ||||||
|         <div class="update-form" style="align-items: center;"> |             <form id="updateForm" enctype='multipart/form-data'> | ||||||
|             <form id="updateForm" enctype='multipart/form-data' style="text-align: center;"></form> |  | ||||||
|                 <input type='file' name='update' accept='.bin' required> |                 <input type='file' name='update' accept='.bin' required> | ||||||
|                 <input type='submit' value='Firmware Update starten'> |                 <input type='submit' value='Start Firmware Update'> | ||||||
|             </form> |             </form> | ||||||
|         </div> |         </div> | ||||||
|  |  | ||||||
| @@ -60,10 +58,21 @@ | |||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
|     <script> |     <script> | ||||||
|  |         // Hide status indicators during update | ||||||
|  |         const statusContainer = document.querySelector('.status-container'); | ||||||
|  |         if (statusContainer) { | ||||||
|  |             statusContainer.style.display = 'none'; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         document.getElementById('updateForm').addEventListener('submit', async (e) => { |         document.getElementById('updateForm').addEventListener('submit', async (e) => { | ||||||
|             e.preventDefault(); |             e.preventDefault(); | ||||||
|             const form = e.target; |             const form = e.target; | ||||||
|             const file = form.update.files[0]; |             const file = form.update.files[0]; | ||||||
|  |             if (!file) { | ||||||
|  |                 alert('Please select a firmware file.'); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             const formData = new FormData(); |             const formData = new FormData(); | ||||||
|             formData.append('update', file); |             formData.append('update', file); | ||||||
|  |  | ||||||
| @@ -91,21 +100,24 @@ | |||||||
|                 try { |                 try { | ||||||
|                     let response = this.responseText; |                     let response = this.responseText; | ||||||
|                     try { |                     try { | ||||||
|                         // Versuche als JSON zu parsen |  | ||||||
|                         const jsonResponse = JSON.parse(response); |                         const jsonResponse = JSON.parse(response); | ||||||
|                         response = jsonResponse.message; |                         response = jsonResponse.message; | ||||||
|                          |                          | ||||||
|                         if (jsonResponse.restart) { |                         if (jsonResponse.restart) { | ||||||
|                             // Wenn Gerät neustartet, warte und lade dann neu |                             status.textContent = response + " Redirecting in 20 seconds..."; | ||||||
|                             status.textContent = response + " Weiterleitung in 5 Sekunden..."; |                             let countdown = 20; | ||||||
|                             setTimeout(() => { |                             const timer = setInterval(() => { | ||||||
|                                 window.location.href = '/'; |                                 countdown--; | ||||||
|                             }, 5000); |                                 if (countdown <= 0) { | ||||||
|  |                                     clearInterval(timer); | ||||||
|  |                                     window.location.href = '/'; | ||||||
|  |                                 } else { | ||||||
|  |                                     status.textContent = response + ` Redirecting in ${countdown} seconds...`; | ||||||
|  |                                 } | ||||||
|  |                             }, 1000); | ||||||
|                         } |                         } | ||||||
|                     } catch (e) { |                     } catch (e) { | ||||||
|                         // Wenn kein JSON, nutze response als Text |  | ||||||
|                         if (!isNaN(response)) { |                         if (!isNaN(response)) { | ||||||
|                             // Wenn es eine Zahl ist, update den Fortschritt |  | ||||||
|                             const percent = parseInt(response); |                             const percent = parseInt(response); | ||||||
|                             progress.style.width = percent + '%'; |                             progress.style.width = percent + '%'; | ||||||
|                             progress.textContent = percent + '%'; |                             progress.textContent = percent + '%'; | ||||||
| @@ -121,7 +133,7 @@ | |||||||
|                         form.querySelector('input[type=submit]').disabled = false; |                         form.querySelector('input[type=submit]').disabled = false; | ||||||
|                     } |                     } | ||||||
|                 } catch (error) { |                 } catch (error) { | ||||||
|                     status.textContent = 'Fehler: ' + error.message; |                     status.textContent = 'Error: ' + error.message; | ||||||
|                     status.classList.add('error'); |                     status.classList.add('error'); | ||||||
|                     status.style.display = 'block'; |                     status.style.display = 'block'; | ||||||
|                     form.querySelector('input[type=submit]').disabled = false; |                     form.querySelector('input[type=submit]').disabled = false; | ||||||
| @@ -129,7 +141,7 @@ | |||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             xhr.onerror = function() { |             xhr.onerror = function() { | ||||||
|                 status.textContent = 'Update fehlgeschlagen: Netzwerkfehler'; |                 status.textContent = 'Update failed: Network error'; | ||||||
|                 status.classList.add('error'); |                 status.classList.add('error'); | ||||||
|                 status.style.display = 'block'; |                 status.style.display = 'block'; | ||||||
|                 form.querySelector('input[type=submit]').disabled = false; |                 form.querySelector('input[type=submit]').disabled = false; | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ | |||||||
|         <div style="display: flex; align-items: center; gap: 2rem;"> |         <div style="display: flex; align-items: center; gap: 2rem;"> | ||||||
|             <img src="/logo.png" alt="FilaMan Logo" class="logo"> |             <img src="/logo.png" alt="FilaMan Logo" class="logo"> | ||||||
|             <div class="logo-text"> |             <div class="logo-text"> | ||||||
|                 <h1>FilaMan<span class="version">v1.2.1</span></h1> |                 <h1>FilaMan<span class="version">v1.2.4</span></h1> | ||||||
|                 <h4>Filament Management Tool</h4> |                 <h4>Filament Management Tool</h4> | ||||||
|             </div> |             </div> | ||||||
|         </div> |         </div> | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| # Name,   Type,  SubType,    Offset,    Size,     Flags | # Name,   Type, SubType,    Offset,   Size,     Flags | ||||||
| nvs,      data,  nvs,       0x9000,   0x5000, | nvs,      data, nvs,       0x9000,   0x5000, | ||||||
| otadata,  data,  ota,       0xe000,   0x2000, | otadata,  data, ota,       0xe000,   0x2000, | ||||||
| app0,     app,   factory,   0x10000,  0x1E0000, | app0,     app,  ota_0,     0x10000,  0x1E0000, | ||||||
| app1,     app,   ota_0,     0x1F0000, 0x1E0000, | app1,     app,  ota_1,     0x1F0000, 0x1E0000, | ||||||
| spiffs,   data,  spiffs,    0x3D0000, 0x30000, | spiffs,   data, spiffs,    0x3D0000, 0x30000, | ||||||
| 
 | 
| @@ -9,7 +9,7 @@ | |||||||
| ; https://docs.platformio.org/page/projectconf.html | ; https://docs.platformio.org/page/projectconf.html | ||||||
|  |  | ||||||
| [common] | [common] | ||||||
| version = "1.2.2" | version = "1.2.6" | ||||||
|  |  | ||||||
| [env:esp32dev] | [env:esp32dev] | ||||||
| platform = espressif32 | platform = espressif32 | ||||||
| @@ -52,6 +52,13 @@ build_flags = | |||||||
|     -DARDUINO_EVENT_RUNNING_CORE=1 |     -DARDUINO_EVENT_RUNNING_CORE=1 | ||||||
|     -DCONFIG_OPTIMIZATION_LEVEL_DEBUG=1 |     -DCONFIG_OPTIMIZATION_LEVEL_DEBUG=1 | ||||||
|     -DCONFIG_ESP32_PANIC_PRINT_REBOOT |     -DCONFIG_ESP32_PANIC_PRINT_REBOOT | ||||||
|  |     -DCONFIG_ARDUINO_OTA_READSIZE=1024 | ||||||
|  |     -DCONFIG_ASYNC_TCP_RUNNING_CORE=1 | ||||||
|  |     -DCONFIG_ASYNC_TCP_USE_WDT=0 | ||||||
|  |     -DCONFIG_LWIP_TCP_MSS=1460 | ||||||
|  |     -DOTA_PARTITION_SUBTYPE=0x10 | ||||||
|  |     -DPARTITION_TABLE_OFFSET=0x8000 | ||||||
|  |     -DPARTITION_TABLE_SIZE=0x1000 | ||||||
|      |      | ||||||
| extra_scripts =  | extra_scripts =  | ||||||
|     scripts/extra_script.py |     scripts/extra_script.py | ||||||
|   | |||||||
							
								
								
									
										235
									
								
								src/ota.cpp
									
									
									
									
									
								
							
							
						
						
									
										235
									
								
								src/ota.cpp
									
									
									
									
									
								
							| @@ -3,219 +3,44 @@ | |||||||
| #include <Update.h> | #include <Update.h> | ||||||
| #include <SPIFFS.h> | #include <SPIFFS.h> | ||||||
| #include "commonFS.h" | #include "commonFS.h" | ||||||
| #include <esp_task_wdt.h> |  | ||||||
| #include <esp_int_wdt.h> |  | ||||||
| #include <esp_pthread.h> |  | ||||||
| #include <esp_ota_ops.h> |  | ||||||
|  |  | ||||||
| // Reduzierter Puffer für Dateioperationen |  | ||||||
| const size_t BUFFER_SIZE = 128; |  | ||||||
| const size_t MIN_FREE_HEAP = 32768; // 32KB minimum free heap |  | ||||||
|  |  | ||||||
| // Files to backup before update |  | ||||||
| const char* CONFIG_FILES[] = { |  | ||||||
|     "/bambu_credentials.json", |  | ||||||
|     "/spoolman_url.json" |  | ||||||
| }; |  | ||||||
| const int CONFIG_FILES_COUNT = sizeof(CONFIG_FILES) / sizeof(CONFIG_FILES[0]); |  | ||||||
|  |  | ||||||
| bool backupConfigs() { |  | ||||||
|     if (!SPIFFS.begin(true)) { |  | ||||||
|         Serial.println("Failed to mount SPIFFS"); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     for (int i = 0; i < CONFIG_FILES_COUNT; i++) { |  | ||||||
|         if (SPIFFS.exists(CONFIG_FILES[i])) { |  | ||||||
|             String backupFile = String(CONFIG_FILES[i]) + ".bak"; |  | ||||||
|              |  | ||||||
|             if (SPIFFS.exists(backupFile)) { |  | ||||||
|                 SPIFFS.remove(backupFile); |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             File sourceFile = SPIFFS.open(CONFIG_FILES[i], "r"); |  | ||||||
|             File destFile = SPIFFS.open(backupFile, "w"); |  | ||||||
|              |  | ||||||
|             if (!sourceFile || !destFile) { |  | ||||||
|                 Serial.printf("Failed to open files for backup: %s\n", CONFIG_FILES[i]); |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // Verwenden Sie einen kleineren Puffer |  | ||||||
|             uint8_t* buf = (uint8_t*)malloc(BUFFER_SIZE); |  | ||||||
|             if (!buf) { |  | ||||||
|                 Serial.println("Failed to allocate buffer"); |  | ||||||
|                 sourceFile.close(); |  | ||||||
|                 destFile.close(); |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             size_t len = 0; |  | ||||||
|             bool success = true; |  | ||||||
|             while ((len = sourceFile.read(buf, BUFFER_SIZE)) > 0) { |  | ||||||
|                 if (destFile.write(buf, len) != len) { |  | ||||||
|                     Serial.println("Write failed"); |  | ||||||
|                     success = false; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             free(buf); |  | ||||||
|             sourceFile.close(); |  | ||||||
|             destFile.close(); |  | ||||||
|  |  | ||||||
|             if (!success) { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     return true; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bool restoreConfigs() { |  | ||||||
|     if (!SPIFFS.begin(true)) { |  | ||||||
|         Serial.println("Failed to mount SPIFFS"); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool success = true; |  | ||||||
|     for (int i = 0; i < CONFIG_FILES_COUNT; i++) { |  | ||||||
|         String backupFile = String(CONFIG_FILES[i]) + ".bak"; |  | ||||||
|         if (SPIFFS.exists(backupFile)) { |  | ||||||
|             if (SPIFFS.exists(CONFIG_FILES[i])) { |  | ||||||
|                 SPIFFS.remove(CONFIG_FILES[i]); |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|             File sourceFile = SPIFFS.open(backupFile, "r"); |  | ||||||
|             File destFile = SPIFFS.open(CONFIG_FILES[i], "w"); |  | ||||||
|              |  | ||||||
|             if (!sourceFile || !destFile) { |  | ||||||
|                 Serial.printf("Failed to open files for restore: %s\n", CONFIG_FILES[i]); |  | ||||||
|                 success = false; |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             // Verwenden Sie einen kleineren Puffer |  | ||||||
|             uint8_t* buf = (uint8_t*)malloc(BUFFER_SIZE); |  | ||||||
|             if (!buf) { |  | ||||||
|                 Serial.println("Failed to allocate buffer"); |  | ||||||
|                 sourceFile.close(); |  | ||||||
|                 destFile.close(); |  | ||||||
|                 success = false; |  | ||||||
|                 continue; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             size_t len = 0; |  | ||||||
|             while ((len = sourceFile.read(buf, BUFFER_SIZE)) > 0) { |  | ||||||
|                 if (destFile.write(buf, len) != len) { |  | ||||||
|                     Serial.println("Write failed"); |  | ||||||
|                     success = false; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             free(buf); |  | ||||||
|             sourceFile.close(); |  | ||||||
|             destFile.close(); |  | ||||||
|              |  | ||||||
|             SPIFFS.remove(backupFile); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     return success; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { | void handleOTAUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) { | ||||||
|     static bool updateStarted = false; |     static size_t contentLength = 0; | ||||||
|     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) { |  | ||||||
|             request->send(500, "text/plain", "Not enough memory available"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (totalSize == 0) { |  | ||||||
|             request->send(400, "text/plain", "Invalid file size"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         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()); |  | ||||||
|  |  | ||||||
|         // Backup configs first |  | ||||||
|         if (!backupConfigs()) { |  | ||||||
|             request->send(500, "text/plain", "Failed to backup configuration"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Close all files and unmount SPIFFS |  | ||||||
|         SPIFFS.end(); |  | ||||||
|  |  | ||||||
|         // Begin update with minimal configuration |  | ||||||
|         if (!Update.begin(totalSize)) { |  | ||||||
|             Serial.printf("Update.begin failed: %s\n", Update.errorString()); |  | ||||||
|             request->send(500, "text/plain", "Failed to start update"); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         updateStarted = true; |  | ||||||
|         Serial.println("Update process started"); |  | ||||||
|          |  | ||||||
|         // Send initial progress |  | ||||||
|         request->send(200, "text/plain", "0"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (!updateStarted) { |  | ||||||
|         request->send(500, "text/plain", "Update not properly started"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Write update data |  | ||||||
|     if (Update.write(data, len) != len) { |  | ||||||
|         Serial.printf("Update.write failed: %s\n", Update.errorString()); |  | ||||||
|         Update.abort(); |  | ||||||
|         request->send(500, "text/plain", "Error during update"); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     totalBytes += len; |  | ||||||
|      |      | ||||||
|     // Send progress update |     if (!index) { | ||||||
|     if (!final) { |         contentLength = request->contentLength(); | ||||||
|         int progress = (totalBytes * 100) / totalSize; |         Serial.printf("Update size: %u bytes\n", contentLength); | ||||||
|         request->send(200, "text/plain", String(progress)); |          | ||||||
|  |         if (contentLength == 0) { | ||||||
|  |             request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Invalid file size\"}"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!Update.begin(contentLength)) { | ||||||
|  |             Serial.printf("Not enough space: %u required\n", contentLength); | ||||||
|  |             request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Not enough space available\"}"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         Serial.println("Update started"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (Update.write(data, len) != len) { | ||||||
|  |         Update.printError(Serial); | ||||||
|  |         request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Error writing update\"}"); | ||||||
|  |         return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (final) { |     if (final) { | ||||||
|         if (!Update.end(true)) { |         if (Update.end(true)) { | ||||||
|             Serial.printf("Update.end failed: %s\n", Update.errorString()); |             Serial.println("Update complete"); | ||||||
|             request->send(500, "text/plain", "Update failed"); |             request->send(200, "application/json", "{\"status\":\"success\",\"message\":\"Update successful! Device will restart...\",\"restart\":true}"); | ||||||
|             return; |             delay(1000); | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Try to restore configs |  | ||||||
|         if (!SPIFFS.begin(true)) { |  | ||||||
|             Serial.println("Failed to mount SPIFFS for restore"); |  | ||||||
|             request->send(200, "application/json", "{\"status\": \"success\", \"message\": \"Update successful but config restore failed. Device will restart...\", \"restart\": true}"); |  | ||||||
|             delay(2000); |  | ||||||
|             ESP.restart(); |             ESP.restart(); | ||||||
|             return; |         } else { | ||||||
|  |             Update.printError(Serial); | ||||||
|  |             request->send(400, "application/json", "{\"status\":\"error\",\"message\":\"Update failed\"}"); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!restoreConfigs()) { |  | ||||||
|             Serial.println("Failed to restore configs"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         request->send(200, "application/json", "{\"status\": \"success\", \"message\": \"Update successful! Device will restart...\", \"restart\": true}"); |  | ||||||
|         delay(2000); |  | ||||||
|         ESP.restart(); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -164,7 +164,7 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|     // Route für about |     // Route für about | ||||||
|     server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){ |     server.on("/about", HTTP_GET, [](AsyncWebServerRequest *request){ | ||||||
|         Serial.println("Anfrage für /about erhalten"); |         Serial.println("Anfrage für /about erhalten"); | ||||||
|         AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/about.html.gz", "text/html"); |         AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/index.html.gz", "text/html"); | ||||||
|         response->addHeader("Content-Encoding", "gzip"); |         response->addHeader("Content-Encoding", "gzip"); | ||||||
|         response->addHeader("Cache-Control", CACHE_CONTROL); |         response->addHeader("Cache-Control", CACHE_CONTROL); | ||||||
|         request->send(response); |         request->send(response); | ||||||
| @@ -338,8 +338,13 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|         Serial.println("RFID.js gesendet"); |         Serial.println("RFID.js gesendet"); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     // Route für Firmware Update |     // Route for Firmware Update | ||||||
|     server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest *request) { |     server.on("/upgrade", HTTP_GET, [](AsyncWebServerRequest *request) { | ||||||
|  |         // During OTA, reduce memory usage | ||||||
|  |         ws.enable(false);  // Temporarily disable WebSocket | ||||||
|  |         ws.cleanupClients(); | ||||||
|  |          | ||||||
|  |         Serial.println("Request for /upgrade received"); | ||||||
|         AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/upgrade.html.gz", "text/html"); |         AsyncWebServerResponse *response = request->beginResponse(SPIFFS, "/upgrade.html.gz", "text/html"); | ||||||
|         response->addHeader("Content-Encoding", "gzip"); |         response->addHeader("Content-Encoding", "gzip"); | ||||||
|         response->addHeader("Cache-Control", CACHE_CONTROL); |         response->addHeader("Cache-Control", CACHE_CONTROL); | ||||||
| @@ -350,7 +355,12 @@ void setupWebserver(AsyncWebServer &server) { | |||||||
|         [](AsyncWebServerRequest *request) { |         [](AsyncWebServerRequest *request) { | ||||||
|             // The response will be sent from handleOTAUpload when the upload is complete |             // The response will be sent from handleOTAUpload when the upload is complete | ||||||
|         }, |         }, | ||||||
|         handleOTAUpload |         [](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) { | ||||||
|  |             // Free memory before handling update | ||||||
|  |             ws.enable(false); | ||||||
|  |             ws.cleanupClients(); | ||||||
|  |             handleOTAUpload(request, filename, index, data, len, final); | ||||||
|  |         } | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|     // Fehlerbehandlung für nicht gefundene Seiten |     // Fehlerbehandlung für nicht gefundene Seiten | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user