From 2a3c0a7911be3531e0a30c01c9cf0d58e013951c Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 18:07:47 +0100 Subject: [PATCH 01/32] Add Forgejo CI action --- .forgejo/workflows/push.yaml | 173 +++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 .forgejo/workflows/push.yaml diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml new file mode 100644 index 0000000..992b782 --- /dev/null +++ b/.forgejo/workflows/push.yaml @@ -0,0 +1,173 @@ +on: + push: + tags: + - "*" + branches: + - 'feature/forgejo-ci' + workflow_dispatch: + +jobs: + build: + runs-on: docker + container: + image: ghcr.io/catthehacker/ubuntu:js-22.04 + permissions: + contents: write + checks: write + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: yarn + cache-dependency-path: '**/yarn.lock' + - uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/.platformio/.cache + ~/data/node_modules + key: ${{ runner.os }}-pio + - uses: actions/setup-python@v5 + with: + python-version: '3.9' + - name: Get current date + id: dateAndTime + shell: bash + run: echo "dateAndTime=$(date +'%Y-%m-%d-%H:%M')" >> $GITHUB_OUTPUT + - name: Install PlatformIO Core + shell: bash + run: pip install --upgrade platformio + - name: Run unit tests + shell: bash + run: mkdir -p junit-reports && pio test -e native_test_only --junit-output-path junit-reports/ + - name: Publish Test Report + uses: mikepenz/action-junit-report@v4 + if: success() || failure() # always run even if the previous step fails + with: + report_paths: '**/junit-reports/*.xml' + detailed_summary: true + - name: Build BTClock firmware + shell: bash + run: pio run + - name: Build BTClock filesystem + shell: bash + run: pio run --target buildfs + - name: Copy bootloader to output folder + run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin .pio + - name: Upload artifacts + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + with: + include-hidden-files: true + retention-days: 1 + name: prepared-outputs + path: .pio/**/*.bin + merge: + runs-on: docker + container: + image: ghcr.io/catthehacker/ubuntu:js-22.04 + permissions: + contents: write + checks: write + needs: build + continue-on-error: true + strategy: + matrix: + chip: + - name: lolin_s3_mini + version: esp32s3 + - name: btclock_rev_b + version: esp32s3 + - name: btclock_v8 + version: esp32s3 + epd_variant: [213epd, 29epd] + exclude: + - chip: {name: btclock_rev_b, version: esp32s3} + epd_variant: 29epd + - chip: {name: btclock_v8, version: esp32s3} + epd_variant: 29epd + steps: + - uses: https://code.forgejo.org/forgejo/download-artifact@v4 + with: + name: prepared-outputs + path: .pio + - name: Install esptools.py + run: pip install --upgrade esptool + - name: Create merged firmware binary + run: | + if [ "${{ matrix.chip.name }}" == "btclock_v8" ]; then + mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ + esptool.py --chip ${{ matrix.chip.version }} merge_bin \ + -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ + --flash_mode dio \ + --flash_freq 80m \ + --flash_size 16MB \ + 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ + 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ + 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ + 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ + 0x810000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin; + else + # Original command for other cases + mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ + esptool.py --chip ${{ matrix.chip.version }} merge_bin \ + -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ + --flash_mode dio \ + 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ + 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ + 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ + 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ + 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin + # Adjust the offset for littlefs or other files as needed for the original case + fi + + - name: Create checksum for firmware + run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin.sha256 + + - name: Create checksum for merged binary + run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin.sha256 + + - name: Create checksum for littlefs partition + run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin.sha256 + + - name: Copy all artifacts to output folder + run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} + + - name: Create OTA binary file + run: mv ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin + - name: Upload artifacts + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + with: + name: build-${{ matrix.chip.name }}-${{ matrix.epd_variant }} + path: | + ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin + ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.sha256 + release: + runs-on: docker + permissions: + contents: write + checks: write + needs: merge + steps: + - name: Download matrix outputs + uses: https://code.forgejo.org/forgejo/download-artifact@v4 + with: + pattern: "build-*/**/*.bin,build-*/**/*.sha256" + merge-multiple: false + path: release + - name: Create release + uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 + with: + url: 'https://git.btclock.dev/' + repo: '${{ github.repository }}' + direction: upload + tag: '${{ github.ref_name }}' + sha: '${{ github.sha }}' + release-dir: release + token: ${{ secrets.TOKEN }} + override: false + verbose: false + prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} + release-notes-assistant: false \ No newline at end of file From 44a6c44e7a10597cfa4006f55b5ac5a16d4bd2e4 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 18:08:54 +0100 Subject: [PATCH 02/32] Remove report action --- .forgejo/workflows/push.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 992b782..132e662 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -43,12 +43,6 @@ jobs: - name: Run unit tests shell: bash run: mkdir -p junit-reports && pio test -e native_test_only --junit-output-path junit-reports/ - - name: Publish Test Report - uses: mikepenz/action-junit-report@v4 - if: success() || failure() # always run even if the previous step fails - with: - report_paths: '**/junit-reports/*.xml' - detailed_summary: true - name: Build BTClock firmware shell: bash run: pio run From e44d686218ebfa87d059a6dc45cad1a409b3e830 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 18:37:50 +0100 Subject: [PATCH 03/32] Fix release step --- .forgejo/workflows/push.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 132e662..b54425b 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -148,9 +148,13 @@ jobs: - name: Download matrix outputs uses: https://code.forgejo.org/forgejo/download-artifact@v4 with: - pattern: "build-*/**/*.bin,build-*/**/*.sha256" + pattern: build-* merge-multiple: false - path: release + path: temp + - name: Copy files + run: | + mkdir -p release + cp -t release temp/**/*.bin temp/**/*.sha256 - name: Create release uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 with: From 25dcf444c2ea04a46c55d81197d030b6368b6461 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 19:03:48 +0100 Subject: [PATCH 04/32] Add platformio and node_modules cache --- .forgejo/workflows/push.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index b54425b..07ac8c8 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -29,6 +29,8 @@ jobs: ~/.cache/pip ~/.platformio/.cache ~/data/node_modules + .pio + data/node_modules key: ${{ runner.os }}-pio - uses: actions/setup-python@v5 with: @@ -154,7 +156,7 @@ jobs: - name: Copy files run: | mkdir -p release - cp -t release temp/**/*.bin temp/**/*.sha256 + cp -rf -t release temp/**/*.bin temp/**/*.sha256 - name: Create release uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 with: @@ -165,7 +167,7 @@ jobs: sha: '${{ github.sha }}' release-dir: release token: ${{ secrets.TOKEN }} - override: false + override: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} verbose: false prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} release-notes-assistant: false \ No newline at end of file From b26ca1e760d32caa4007c657727d2b334120e1c9 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 19:29:37 +0100 Subject: [PATCH 05/32] Try with less targets --- .forgejo/workflows/push.yaml | 3 ++- platformio.ini | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 07ac8c8..602897f 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -35,6 +35,7 @@ jobs: - uses: actions/setup-python@v5 with: python-version: '3.9' + cache: 'pip' - name: Get current date id: dateAndTime shell: bash @@ -156,7 +157,7 @@ jobs: - name: Copy files run: | mkdir -p release - cp -rf -t release temp/**/*.bin temp/**/*.sha256 + find temp -type f \( -name "*.bin" -o -name "*.sha256" \) -exec cp -f {} release/ \; - name: Create release uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 with: diff --git a/platformio.ini b/platformio.ini index 25e7d9c..28ccda0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] data_dir = data/build_gz -default_envs = lolin_s3_mini_213epd, lolin_s3_mini_29epd, btclock_rev_b_213epd, btclock_v8_213epd +default_envs = lolin_s3_mini_213epd, lolin_s3_mini_29epd [env] From d3725d6ae1f7af84cae9380f63b829c69e84189e Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 19:42:36 +0100 Subject: [PATCH 06/32] Disable more --- .forgejo/workflows/push.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 602897f..5aff65b 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -75,10 +75,10 @@ jobs: chip: - name: lolin_s3_mini version: esp32s3 - - name: btclock_rev_b - version: esp32s3 - - name: btclock_v8 - version: esp32s3 + # - name: btclock_rev_b + # version: esp32s3 + # - name: btclock_v8 + # version: esp32s3 epd_variant: [213epd, 29epd] exclude: - chip: {name: btclock_rev_b, version: esp32s3} From 684cd7e05cc832cc15ee2ac87b12af209433b1a5 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 19:58:10 +0100 Subject: [PATCH 07/32] Restore all variants --- .forgejo/workflows/push.yaml | 12 ++++++------ platformio.ini | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 5aff65b..86c0ed6 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -75,10 +75,10 @@ jobs: chip: - name: lolin_s3_mini version: esp32s3 - # - name: btclock_rev_b - # version: esp32s3 - # - name: btclock_v8 - # version: esp32s3 + - name: btclock_rev_b + version: esp32s3 + - name: btclock_v8 + version: esp32s3 epd_variant: [213epd, 29epd] exclude: - chip: {name: btclock_rev_b, version: esp32s3} @@ -161,7 +161,7 @@ jobs: - name: Create release uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 with: - url: 'https://git.btclock.dev/' + url: 'https://git.btclock.dev' repo: '${{ github.repository }}' direction: upload tag: '${{ github.ref_name }}' @@ -169,6 +169,6 @@ jobs: release-dir: release token: ${{ secrets.TOKEN }} override: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} - verbose: false + verbose: ${{ vars.VERBOSE || "false" }} prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} release-notes-assistant: false \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 28ccda0..25e7d9c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] data_dir = data/build_gz -default_envs = lolin_s3_mini_213epd, lolin_s3_mini_29epd +default_envs = lolin_s3_mini_213epd, lolin_s3_mini_29epd, btclock_rev_b_213epd, btclock_v8_213epd [env] From 9f3351f85bdd8c8e0d892db3d2030f737b107065 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 18:07:47 +0100 Subject: [PATCH 08/32] Add Forgejo CI action Remove report action Fix release step Add platformio and node_modules cache Try with less targets Disable more Restore all variants Remove verbose and feature branch run --- .forgejo/workflows/push.yaml | 171 +++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 .forgejo/workflows/push.yaml diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml new file mode 100644 index 0000000..81fdc06 --- /dev/null +++ b/.forgejo/workflows/push.yaml @@ -0,0 +1,171 @@ +on: + push: + tags: + - "*" + workflow_dispatch: + +jobs: + build: + runs-on: docker + container: + image: ghcr.io/catthehacker/ubuntu:js-22.04 + permissions: + contents: write + checks: write + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions/setup-node@v4 + with: + node-version: lts/* + cache: yarn + cache-dependency-path: '**/yarn.lock' + - uses: actions/cache@v4 + with: + path: | + ~/.cache/pip + ~/.platformio/.cache + ~/data/node_modules + .pio + data/node_modules + key: ${{ runner.os }}-pio + - uses: actions/setup-python@v5 + with: + python-version: '3.9' + cache: 'pip' + - name: Get current date + id: dateAndTime + shell: bash + run: echo "dateAndTime=$(date +'%Y-%m-%d-%H:%M')" >> $GITHUB_OUTPUT + - name: Install PlatformIO Core + shell: bash + run: pip install --upgrade platformio + - name: Run unit tests + shell: bash + run: mkdir -p junit-reports && pio test -e native_test_only --junit-output-path junit-reports/ + - name: Build BTClock firmware + shell: bash + run: pio run + - name: Build BTClock filesystem + shell: bash + run: pio run --target buildfs + - name: Copy bootloader to output folder + run: cp ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin .pio + - name: Upload artifacts + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + with: + include-hidden-files: true + retention-days: 1 + name: prepared-outputs + path: .pio/**/*.bin + merge: + runs-on: docker + container: + image: ghcr.io/catthehacker/ubuntu:js-22.04 + permissions: + contents: write + checks: write + needs: build + continue-on-error: true + strategy: + matrix: + chip: + - name: lolin_s3_mini + version: esp32s3 + - name: btclock_rev_b + version: esp32s3 + - name: btclock_v8 + version: esp32s3 + epd_variant: [213epd, 29epd] + exclude: + - chip: {name: btclock_rev_b, version: esp32s3} + epd_variant: 29epd + - chip: {name: btclock_v8, version: esp32s3} + epd_variant: 29epd + steps: + - uses: https://code.forgejo.org/forgejo/download-artifact@v4 + with: + name: prepared-outputs + path: .pio + - name: Install esptools.py + run: pip install --upgrade esptool + - name: Create merged firmware binary + run: | + if [ "${{ matrix.chip.name }}" == "btclock_v8" ]; then + mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ + esptool.py --chip ${{ matrix.chip.version }} merge_bin \ + -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ + --flash_mode dio \ + --flash_freq 80m \ + --flash_size 16MB \ + 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ + 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ + 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ + 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ + 0x810000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin; + else + # Original command for other cases + mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ + esptool.py --chip ${{ matrix.chip.version }} merge_bin \ + -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ + --flash_mode dio \ + 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ + 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ + 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ + 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ + 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin + # Adjust the offset for littlefs or other files as needed for the original case + fi + + - name: Create checksum for firmware + run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin.sha256 + + - name: Create checksum for merged binary + run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin.sha256 + + - name: Create checksum for littlefs partition + run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin.sha256 + + - name: Copy all artifacts to output folder + run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} + + - name: Create OTA binary file + run: mv ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin + - name: Upload artifacts + uses: https://code.forgejo.org/forgejo/upload-artifact@v4 + with: + name: build-${{ matrix.chip.name }}-${{ matrix.epd_variant }} + path: | + ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin + ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.sha256 + release: + runs-on: docker + permissions: + contents: write + checks: write + needs: merge + steps: + - name: Download matrix outputs + uses: https://code.forgejo.org/forgejo/download-artifact@v4 + with: + pattern: build-* + merge-multiple: false + path: temp + - name: Copy files + run: | + mkdir -p release + find temp -type f \( -name "*.bin" -o -name "*.sha256" \) -exec cp -f {} release/ \; + - name: Create release + uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 + with: + url: 'https://git.btclock.dev' + repo: '${{ github.repository }}' + direction: upload + tag: '${{ github.ref_name }}' + sha: '${{ github.sha }}' + release-dir: release + token: ${{ secrets.TOKEN }} + override: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} + prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} + release-notes-assistant: false \ No newline at end of file From 3b47c81cfe06028fdc12e583e4d36b23b710a2b9 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 20:50:32 +0100 Subject: [PATCH 09/32] Webserver dependency update and testing new CI flow --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 25e7d9c..021a03d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -34,7 +34,7 @@ build_unflags = lib_deps = https://github.com/joltwallet/esp_littlefs.git bblanchon/ArduinoJson@^7.2.0 - mathieucarbou/ESPAsyncWebServer @ 3.3.7 + mathieucarbou/ESPAsyncWebServer @ 3.3.23 adafruit/Adafruit BusIO@^1.16.1 adafruit/Adafruit MCP23017 Arduino Library@^2.3.2 adafruit/Adafruit NeoPixel@^1.12.3 From 239297c26d586aad885c1598947baca4eebd4950 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 26 Nov 2024 21:48:28 +0100 Subject: [PATCH 10/32] Add own badges to README --- .forgejo/workflows/push.yaml | 2 ++ README.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 81fdc06..b48a34e 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -1,3 +1,5 @@ +name: 'BTClock CI' + on: push: tags: diff --git a/README.md b/README.md index 5dfc0ad..81890b4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # BTClock v3 -[![BTClock CI](https://github.com/btclock/btclock_v3/actions/workflows/tagging.yml/badge.svg)](https://github.com/btclock/btclock_v3/actions/workflows/tagging.yml) +[![Latest release](https://git.btclock.dev/btclock/btclock_v3/badges/release.svg)](https://git.btclock.dev/btclock/btclock_v3/releases/latest) + +[![BTClock CI](https://git.btclock.dev/btclock/btclock_v3/badges/workflows/push.yaml/badge.svg)](https://git.btclock.dev/btclock/btclock_v3/actions?workflow=push.yaml&actor=0&status=0) Software for the BTClock project. From d37307cccfea6b35dfb149b6e3d5248d9a8460b3 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 27 Nov 2024 11:33:12 +0100 Subject: [PATCH 11/32] Add Mow mode notation and setting --- data | 2 +- lib/btclock/data_handler.cpp | 4 +- lib/btclock/data_handler.hpp | 2 +- lib/btclock/utils.cpp | 25 ++++++++--- lib/btclock/utils.hpp | 1 + src/lib/defaults.hpp | 2 + src/lib/epd.cpp | 70 +++++++++++++++++++++++++++-- src/lib/screen_handler.cpp | 2 +- src/lib/webserver.cpp | 2 + test/test_datahandler/test_main.cpp | 29 ++++++++++++ 10 files changed, 124 insertions(+), 15 deletions(-) diff --git a/data b/data index 5066032..d74e9da 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 5066032a55b5436ec5c888cf0eb91bdc9e71bea0 +Subproject commit d74e9dab60772ef11f9b033cfe982d216a9c95ee diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index 7b63db6..3209811 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -67,13 +67,13 @@ char getCurrencyChar(const std::string& input) return CURRENCY_USD; // Assuming USD is the default for unknown inputs } -std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat) +std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat, bool mowMode) { std::array ret; std::string priceString; if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat) { - priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, NUM_SCREENS - 2); + priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, NUM_SCREENS - 2, mowMode); } else { diff --git a/lib/btclock/data_handler.hpp b/lib/btclock/data_handler.hpp index 2d563a4..f8e237c 100644 --- a/lib/btclock/data_handler.hpp +++ b/lib/btclock/data_handler.hpp @@ -19,7 +19,7 @@ const std::string CURRENCY_CODE_JPY = "JPY"; const std::string CURRENCY_CODE_AUD = "AUD"; const std::string CURRENCY_CODE_CAD = "CAD"; -std::array parsePriceData(std::uint32_t price, char currency, bool useSuffixFormat = false); +std::array parsePriceData(std::uint32_t price, char currency, bool useSuffixFormat = false, bool mowMode = false); std::array parseSatsPerCurrency(std::uint32_t price, char currencySymbol, bool withSatsSymbol); std::array parseBlockHeight(std::uint32_t blockHeight); std::array parseHalvingCountdown(std::uint32_t blockHeight, bool asBlocks); diff --git a/lib/btclock/utils.cpp b/lib/btclock/utils.cpp index 53212e4..9056d14 100644 --- a/lib/btclock/utils.cpp +++ b/lib/btclock/utils.cpp @@ -28,7 +28,12 @@ double getSupplyAtBlock(std::uint32_t blockNr) return totalBitcoinInCirculation; } -std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters) +std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters) +{ + return formatNumberWithSuffix(num, numCharacters, false); +} + +std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters, bool mowMode) { static char result[20]; // Adjust size as needed const long long quadrillion = 1000000000000000LL; @@ -56,30 +61,36 @@ std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters) numDouble /= billion; suffix = 'B'; } - else if (num >= million || numDigits > 6) + else if (num >= million || numDigits > 6 || (mowMode && num >= thousand)) { numDouble /= million; suffix = 'M'; } - else if (num >= thousand || numDigits > 3) + else if (!mowMode && (num >= thousand || numDigits > 3)) { numDouble /= thousand; suffix = 'K'; } - else + else if (!mowMode) { snprintf(result, sizeof(result), "%llu", (unsigned long long)num); -// sprintf(result, "%llu", (unsigned long long)num); return result; } + else // mowMode is true and num < 1000 + { + numDouble /= million; + suffix = 'M'; + } // Add suffix int len = snprintf(result, sizeof(result), "%.0f%c", numDouble, suffix); - // If there's room, add decimal places + // If there's room, add more decimal places if (len < numCharacters) { - snprintf(result, sizeof(result), "%.*f%c", numCharacters - len - 1, numDouble, suffix); + int restLen = mowMode ? numCharacters - len : numCharacters - len - 1; + + snprintf(result, sizeof(result), "%.*f%c", restLen, numDouble, suffix); } return result; diff --git a/lib/btclock/utils.hpp b/lib/btclock/utils.hpp index b166cae..cf4a107 100644 --- a/lib/btclock/utils.hpp +++ b/lib/btclock/utils.hpp @@ -11,4 +11,5 @@ int modulo(int x,int N); double getSupplyAtBlock(std::uint32_t blockNr); std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters = 4); +std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters, bool mowMode); int64_t getAmountInSatoshis(std::string bolt11); \ No newline at end of file diff --git a/src/lib/defaults.hpp b/src/lib/defaults.hpp index dd222a5..c665b3b 100644 --- a/src/lib/defaults.hpp +++ b/src/lib/defaults.hpp @@ -18,6 +18,8 @@ #define DEFAULT_DISABLE_FL false #define DEFAULT_OWN_DATA_SOURCE true #define DEFAULT_STAGING_SOURCE false +#define DEFAULT_MOW_MODE false + #define DEFAULT_V2_SOURCE_CURRENCY CURRENCY_USD diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index a301f17..eac002c 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -283,7 +283,10 @@ void prepareDisplayUpdateTask(void *pvParameters) } else { - if (epdContent[epdIndex].length() > 1 && epdContent[epdIndex].indexOf(".") == -1) + if (epdContent[epdIndex].length() == 2) { + showChars(epdIndex, epdContent[epdIndex], updatePartial, &FONT_BIG); + } + else if (epdContent[epdIndex].length() > 1 && epdContent[epdIndex].indexOf(".") == -1) { if (epdContent[epdIndex].equals("STS")) { @@ -407,6 +410,32 @@ void splitText(const uint dispNum, const String &top, const String &bottom, displays[dispNum].print(bottom); } +// void showChars(const uint dispNum, const String &chars, bool partial, +// const GFXfont *font) +// { +// displays[dispNum].setRotation(2); +// displays[dispNum].setFont(font); +// displays[dispNum].setTextColor(getFgColor()); +// int16_t tbx, tby; +// uint16_t tbw, tbh; + +// displays[dispNum].getTextBounds(chars, 0, 0, &tbx, &tby, &tbw, &tbh); + +// // center the bounding box by transposition of the origin: +// uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx; +// uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby; + +// displays[dispNum].fillScreen(getBgColor()); + +// displays[dispNum].setCursor(x, y); +// displays[dispNum].print(chars); + +// // displays[dispNum].setCursor(10, 3); +// // displays[dispNum].setFont(&FONT_SMALL); +// // displays[dispNum].setTextColor(getFgColor()); +// // displays[dispNum].println("Y = " + y); +// } + void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font) { @@ -466,6 +495,18 @@ void showDigit(const uint dispNum, char chr, bool partial, // displays[dispNum].println("Y = " + y); } +int16_t calculateDescent(const GFXfont *font) { + int16_t maxDescent = 0; + for (uint16_t i = font->first; i <= font->last; i++) { + GFXglyph *glyph = &font->glyph[i - font->first]; + int16_t descent = glyph->yOffset; + if (descent > maxDescent) { + maxDescent = descent; + } + } + return maxDescent; +} + void showChars(const uint dispNum, const String &chars, bool partial, const GFXfont *font) { @@ -475,12 +516,35 @@ void showChars(const uint dispNum, const String &chars, bool partial, int16_t tbx, tby; uint16_t tbw, tbh; displays[dispNum].getTextBounds(chars, 0, 0, &tbx, &tby, &tbw, &tbh); + + int16_t descent = calculateDescent(font); + // center the bounding box by transposition of the origin: uint16_t x = ((displays[dispNum].width() - tbw) / 2) - tbx; uint16_t y = ((displays[dispNum].height() - tbh) / 2) - tby; displays[dispNum].fillScreen(getBgColor()); - displays[dispNum].setCursor(x, y); - displays[dispNum].print(chars); + // displays[dispNum].setCursor(x, y); + // displays[dispNum].print(chars); + + for (int i = 0; i < chars.length(); i++) { + char c = chars[i]; + if (c == '.' || c == ',') { + // For the dot, calculate its specific descent + GFXglyph *dotGlyph = &font->glyph[c -font->first]; + int16_t dotDescent = dotGlyph->yOffset; + + // Draw the dot with adjusted y-position + displays[dispNum].setCursor(x, y + dotDescent + dotGlyph->height); + displays[dispNum].print(c); + } else { + // For other characters, use the original y-position + displays[dispNum].setCursor(x, y); + displays[dispNum].print(c); + } + + // Move x-position for the next character + x += font->glyph[c - font->first].xAdvance; + } } int getBgColor() { return bgColor; } diff --git a/src/lib/screen_handler.cpp b/src/lib/screen_handler.cpp index d1c6165..47ac609 100644 --- a/src/lib/screen_handler.cpp +++ b/src/lib/screen_handler.cpp @@ -41,7 +41,7 @@ void workerTask(void *pvParameters) { uint price = getPrice(currency); if (getCurrentScreen() == SCREEN_BTC_TICKER) { - taskEpdContent = parsePriceData(price, currency, preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE)); + taskEpdContent = parsePriceData(price, currency, preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE), preferences.getBool("mowMode", DEFAULT_MOW_MODE)); } else if (getCurrentScreen() == SCREEN_SATS_PER_CURRENCY) { taskEpdContent = parseSatsPerCurrency(price, currency, preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL)); } else { diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index 7a6d28d..c4ad256 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -546,6 +546,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) "mdnsEnabled", "otaEnabled", "stealFocus", "mcapBigChar", "useSatsSymbol", "useBlkCountdown", "suffixPrice", "disableLeds", "ownDataSource", + "mowMode", "flAlwaysOn", "flDisable", "flFlashOnUpd", "mempoolSecure", "useNostr", "bitaxeEnabled", "nostrZapNotify", "stagingSource", "httpAuthEnabled"}; @@ -687,6 +688,7 @@ void onApiSettingsGet(AsyncWebServerRequest *request) root["useBlkCountdown"] = preferences.getBool("useBlkCountdown", DEFAULT_USE_BLOCK_COUNTDOWN); root["suffixPrice"] = preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE); root["disableLeds"] = preferences.getBool("disableLeds", DEFAULT_DISABLE_LEDS); + root["mowMode"] = preferences.getBool("mowMode", DEFAULT_MOW_MODE); root["hostnamePrefix"] = preferences.getString("hostnamePrefix", DEFAULT_HOSTNAME_PREFIX); root["hostname"] = getMyHostname(); diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index 29d337f..218408c 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -86,6 +86,33 @@ void test_PriceOf1MillionUsd(void) TEST_ASSERT_EQUAL_STRING("M", output[NUM_SCREENS - 1].c_str()); } +void test_PriceSuffixMode(void) +{ + std::array output = parsePriceData(93000, '$', true, false); + TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); + + TEST_ASSERT_EQUAL_STRING("9", output[NUM_SCREENS - 5].c_str()); + TEST_ASSERT_EQUAL_STRING("3", output[NUM_SCREENS - 4].c_str()); + TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 3].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); + TEST_ASSERT_EQUAL_STRING("K", output[NUM_SCREENS - 1].c_str()); +} + +void test_PriceSuffixModeMow(void) +{ + std::array output = parsePriceData(93000, '$', true, true); + + std::string joined = joinArrayWithBrackets(output); + + TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[0].c_str(), joined.c_str()); + + TEST_ASSERT_EQUAL_STRING_MESSAGE(".", output[NUM_SCREENS - 5].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("9", output[NUM_SCREENS - 3].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("3", output[NUM_SCREENS - 2].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); +} + void test_McapLowerUsd(void) { std::array output = parseMarketCap(810000, 26000, '$', true); @@ -203,6 +230,8 @@ int runUnityTests(void) RUN_TEST(test_Mcap1TrillionEurSmallChars); RUN_TEST(test_Mcap1TrillionJpy); RUN_TEST(test_Mcap1TrillionJpySmallChars); + RUN_TEST(test_PriceSuffixMode); + RUN_TEST(test_PriceSuffixModeMow); return UNITY_END(); } From 2951055f68473dfca060d46c56347628edf81da7 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 27 Nov 2024 11:41:58 +0100 Subject: [PATCH 12/32] Add requirements.txt for CI --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a91b030 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +platformio \ No newline at end of file From 4cda081d05e76351cce434b9d6a14298bedb8dcd Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 28 Nov 2024 18:22:07 +0100 Subject: [PATCH 13/32] Add suffix compact mode, added extra zap notify settings, WebUI cleanup --- .forgejo/workflows/push.yaml | 2 +- data | 2 +- dependencies.lock | 2 +- lib/btclock/data_handler.cpp | 40 +++++++++++++++++++++++++---- lib/btclock/data_handler.hpp | 3 ++- partition.csv | 6 ++--- platformio.ini | 4 +-- src/lib/defaults.hpp | 3 +++ src/lib/epd.cpp | 2 +- src/lib/led_handler.cpp | 4 +-- src/lib/nostr_notify.cpp | 5 +++- src/lib/screen_handler.cpp | 5 +++- src/lib/webserver.cpp | 7 ++++- test/test_datahandler/test_main.cpp | 16 ++++++++++++ 14 files changed, 81 insertions(+), 20 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index b48a34e..5121d24 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -116,7 +116,7 @@ jobs: 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin + 0x370000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin # Adjust the offset for littlefs or other files as needed for the original case fi diff --git a/data b/data index d74e9da..de99a22 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit d74e9dab60772ef11f9b033cfe982d216a9c95ee +Subproject commit de99a221d688949da0d95e2f9df2da5ba77f5c0d diff --git a/dependencies.lock b/dependencies.lock index 2cb885d..c338e6c 100644 --- a/dependencies.lock +++ b/dependencies.lock @@ -4,6 +4,6 @@ dependencies: source: type: idf version: 4.4.7 -manifest_hash: 841ba2a95f4b32d39636bf4fdf07c48a2052f71c9728a5b7f263083a3b430a4f +manifest_hash: cd2f3ee15e776d949eb4ea4eddc8f39b30c2a7905050850eed01ab4928143cff target: esp32s3 version: 1.0.0 diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index 3209811..c1f1d1f 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -67,7 +67,7 @@ char getCurrencyChar(const std::string& input) return CURRENCY_USD; // Assuming USD is the default for unknown inputs } -std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat, bool mowMode) +std::array parsePriceData(std::uint32_t price, char currencySymbol, bool useSuffixFormat, bool mowMode, bool shareDot) { std::array ret; std::string priceString; @@ -80,7 +80,7 @@ std::array parsePriceData(std::uint32_t price, char cu priceString = getCurrencySymbol(currencySymbol) + std::to_string(price); } std::uint32_t firstIndex = 0; - if (priceString.length() < (NUM_SCREENS)) + if ((shareDot && priceString.length() <= (NUM_SCREENS)) || priceString.length() < (NUM_SCREENS)) { priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); @@ -89,11 +89,41 @@ std::array parsePriceData(std::uint32_t price, char cu firstIndex = 1; } - - for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++) + + if (shareDot) { - ret[i] = priceString[i]; + std::vector tempArray; + size_t dotPosition = priceString.find('.'); + if (dotPosition != std::string::npos && dotPosition > 0) + { + for (size_t i = 0; i < priceString.length(); ++i) + { + if (i == dotPosition - 1) + { + tempArray.push_back(std::string(1, priceString[i]) + "."); + ++i; // Skip the dot in the next iteration + } + else + { + tempArray.push_back(std::string(1, priceString[i])); + } + } + + // Copy from tempArray to ret + for (std::uint32_t i = firstIndex; i < NUM_SCREENS && i - firstIndex < tempArray.size(); ++i) + { + ret[i] = tempArray[i - firstIndex]; + } + } } + else + { + for (std::uint32_t i = firstIndex; i < NUM_SCREENS; i++) + { + ret[i] = std::string(1, priceString[i]); + } + } + return ret; } diff --git a/lib/btclock/data_handler.hpp b/lib/btclock/data_handler.hpp index f8e237c..4dda86b 100644 --- a/lib/btclock/data_handler.hpp +++ b/lib/btclock/data_handler.hpp @@ -2,6 +2,7 @@ #include #include #include +#include #include "utils.hpp" @@ -19,7 +20,7 @@ const std::string CURRENCY_CODE_JPY = "JPY"; const std::string CURRENCY_CODE_AUD = "AUD"; const std::string CURRENCY_CODE_CAD = "CAD"; -std::array parsePriceData(std::uint32_t price, char currency, bool useSuffixFormat = false, bool mowMode = false); +std::array parsePriceData(std::uint32_t price, char currency, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false); std::array parseSatsPerCurrency(std::uint32_t price, char currencySymbol, bool withSatsSymbol); std::array parseBlockHeight(std::uint32_t blockHeight); std::array parseHalvingCountdown(std::uint32_t blockHeight, bool asBlocks); diff --git a/partition.csv b/partition.csv index 318b4f0..778b9f2 100644 --- a/partition.csv +++ b/partition.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 36K, 20K, otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 1740K, -app1, app, ota_1, , 1740K, -spiffs, data, spiffs, , 400K, +app0, app, ota_0, 64K, 1760K, +app1, app, ota_1, , 1760K, +spiffs, data, spiffs, , 410K, coredump, data, coredump,, 64K, diff --git a/platformio.ini b/platformio.ini index 021a03d..7b0d229 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,9 +33,9 @@ build_unflags = -fno-exceptions lib_deps = https://github.com/joltwallet/esp_littlefs.git - bblanchon/ArduinoJson@^7.2.0 + bblanchon/ArduinoJson@^7.2.1 mathieucarbou/ESPAsyncWebServer @ 3.3.23 - adafruit/Adafruit BusIO@^1.16.1 + adafruit/Adafruit BusIO@^1.16.2 adafruit/Adafruit MCP23017 Arduino Library@^2.3.2 adafruit/Adafruit NeoPixel@^1.12.3 https://github.com/dsbaars/universal_pin diff --git a/src/lib/defaults.hpp b/src/lib/defaults.hpp index c665b3b..8af3b5b 100644 --- a/src/lib/defaults.hpp +++ b/src/lib/defaults.hpp @@ -19,6 +19,7 @@ #define DEFAULT_OWN_DATA_SOURCE true #define DEFAULT_STAGING_SOURCE false #define DEFAULT_MOW_MODE false +#define DEFAULT_SUFFIX_SHARE_DOT false #define DEFAULT_V2_SOURCE_CURRENCY CURRENCY_USD @@ -57,6 +58,8 @@ #define DEFAULT_ZAP_NOTIFY_ENABLED false #define DEFAULT_ZAP_NOTIFY_PUBKEY "b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422" +#define DEFAULT_LED_FLASH_ON_ZAP true +#define DEFAULT_FL_FLASH_ON_ZAP true #define DEFAULT_HTTP_AUTH_ENABLED false #define DEFAULT_HTTP_AUTH_USERNAME "btclock" diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index eac002c..1c04725 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -534,7 +534,7 @@ void showChars(const uint dispNum, const String &chars, bool partial, int16_t dotDescent = dotGlyph->yOffset; // Draw the dot with adjusted y-position - displays[dispNum].setCursor(x, y + dotDescent + dotGlyph->height); + displays[dispNum].setCursor(x, y + dotDescent + dotGlyph->height + 8); displays[dispNum].print(c); } else { // For other characters, use the original y-position diff --git a/src/lib/led_handler.cpp b/src/lib/led_handler.cpp index 4f882e0..338c3c3 100644 --- a/src/lib/led_handler.cpp +++ b/src/lib/led_handler.cpp @@ -285,7 +285,7 @@ void ledTask(void *parameter) #ifdef HAS_FRONTLIGHT bool frontlightWasOn = false; - if (preferences.getBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE)) + if (preferences.getBool("flFlashOnZap", DEFAULT_FL_FLASH_ON_ZAP)) { if (frontlightOn) { @@ -307,7 +307,7 @@ void ledTask(void *parameter) // blinkDelayTwoColor(250, 3, pixels.Color(142, 48, 235), // pixels.Color(169, 21, 255)); #ifdef HAS_FRONTLIGHT - if (preferences.getBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE)) + if (preferences.getBool("flFlashOnZap", DEFAULT_FL_FLASH_ON_ZAP)) { vTaskDelay(pdMS_TO_TICKS(10)); if (frontlightWasOn) diff --git a/src/lib/nostr_notify.cpp b/src/lib/nostr_notify.cpp index 237eabe..bad593d 100644 --- a/src/lib/nostr_notify.cpp +++ b/src/lib/nostr_notify.cpp @@ -252,7 +252,10 @@ void handleNostrZapCallback(const String &subId, nostr::SignedNostrEvent *event) setEpdContent(textEpdContent); vTaskDelay(pdMS_TO_TICKS(315 * NUM_SCREENS) + pdMS_TO_TICKS(250)); - queueLedEffect(LED_EFFECT_NOSTR_ZAP); + if (preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP)) + { + queueLedEffect(LED_EFFECT_NOSTR_ZAP); + } if (timerPeriod > 0) { esp_timer_start_periodic(screenRotateTimer, diff --git a/src/lib/screen_handler.cpp b/src/lib/screen_handler.cpp index 47ac609..1f2b4a4 100644 --- a/src/lib/screen_handler.cpp +++ b/src/lib/screen_handler.cpp @@ -41,7 +41,10 @@ void workerTask(void *pvParameters) { uint price = getPrice(currency); if (getCurrentScreen() == SCREEN_BTC_TICKER) { - taskEpdContent = parsePriceData(price, currency, preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE), preferences.getBool("mowMode", DEFAULT_MOW_MODE)); + taskEpdContent = parsePriceData(price, currency, preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE), + preferences.getBool("mowMode", DEFAULT_MOW_MODE), + preferences.getBool("suffixShareDot", DEFAULT_SUFFIX_SHARE_DOT) + ); } else if (getCurrentScreen() == SCREEN_SATS_PER_CURRENCY) { taskEpdContent = parseSatsPerCurrency(price, currency, preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL)); } else { diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index c4ad256..777fe0b 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -546,7 +546,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) "mdnsEnabled", "otaEnabled", "stealFocus", "mcapBigChar", "useSatsSymbol", "useBlkCountdown", "suffixPrice", "disableLeds", "ownDataSource", - "mowMode", + "mowMode", "suffixShareDot", "flAlwaysOn", "flDisable", "flFlashOnUpd", "mempoolSecure", "useNostr", "bitaxeEnabled", "nostrZapNotify", "stagingSource", "httpAuthEnabled"}; @@ -689,6 +689,7 @@ void onApiSettingsGet(AsyncWebServerRequest *request) root["suffixPrice"] = preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE); root["disableLeds"] = preferences.getBool("disableLeds", DEFAULT_DISABLE_LEDS); root["mowMode"] = preferences.getBool("mowMode", DEFAULT_MOW_MODE); + root["suffixShareDot"] = preferences.getBool("suffixShareDot", DEFAULT_SUFFIX_SHARE_DOT); root["hostnamePrefix"] = preferences.getString("hostnamePrefix", DEFAULT_HOSTNAME_PREFIX); root["hostname"] = getMyHostname(); @@ -703,6 +704,8 @@ void onApiSettingsGet(AsyncWebServerRequest *request) root["nostrZapNotify"] = preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED); root["nostrZapPubkey"] = preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY); + root["ledFlashOnZap"] = preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP); + root["gitReleaseUrl"] = preferences.getString("gitReleaseUrl", DEFAULT_GIT_RELEASE_URL); root["bitaxeEnabled"] = preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED); @@ -719,6 +722,8 @@ void onApiSettingsGet(AsyncWebServerRequest *request) root["flAlwaysOn"] = preferences.getBool("flAlwaysOn", DEFAULT_FL_ALWAYS_ON); root["flEffectDelay"] = preferences.getUInt("flEffectDelay", DEFAULT_FL_EFFECT_DELAY); root["flFlashOnUpd"] = preferences.getBool("flFlashOnUpd", DEFAULT_FL_FLASH_ON_UPDATE); + root["flFlashOnZap"] = preferences.getBool("flFlashOnZap", DEFAULT_FL_FLASH_ON_ZAP); + root["hasLightLevel"] = hasLightLevel(); root["luxLightToggle"] = preferences.getUInt("luxLightToggle", DEFAULT_LUX_LIGHT_TOGGLE); #else diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index 218408c..f2ad64c 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -113,6 +113,21 @@ void test_PriceSuffixModeMow(void) TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); } +void test_PriceSuffixModeMowCompact(void) +{ + std::array output = parsePriceData(93000, '$', true, true, true); + + std::string joined = joinArrayWithBrackets(output); + + TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0.", output[NUM_SCREENS - 5].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("9", output[NUM_SCREENS - 3].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("3", output[NUM_SCREENS - 2].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); +} + void test_McapLowerUsd(void) { std::array output = parseMarketCap(810000, 26000, '$', true); @@ -232,6 +247,7 @@ int runUnityTests(void) RUN_TEST(test_Mcap1TrillionJpySmallChars); RUN_TEST(test_PriceSuffixMode); RUN_TEST(test_PriceSuffixModeMow); + RUN_TEST(test_PriceSuffixModeMowCompact); return UNITY_END(); } From 031b506fedc536e130fb8a5e874b59e3cb051864 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 28 Nov 2024 19:21:15 +0100 Subject: [PATCH 14/32] Fix partition tables for bigger flash sizes --- partition_16mb.csv | 2 +- partition_8mb.csv | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/partition_16mb.csv b/partition_16mb.csv index a32b7ca..e26e145 100644 --- a/partition_16mb.csv +++ b/partition_16mb.csv @@ -3,5 +3,5 @@ nvs, data, nvs, 36K, 20K, otadata, data, ota, 56K, 8K, app0, app, ota_0, 64K, 4096K, app1, app, ota_1, , 4096K, -spiffs, data, spiffs, , 400K, +spiffs, data, spiffs, , 410K, coredump, data, coredump,, 64K, diff --git a/partition_8mb.csv b/partition_8mb.csv index 4ca1357..778b9f2 100644 --- a/partition_8mb.csv +++ b/partition_8mb.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 36K, 20K, otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 1700K, -app1, app, ota_1, , 1700K, -spiffs, data, spiffs, , 400K, +app0, app, ota_0, 64K, 1760K, +app1, app, ota_1, , 1760K, +spiffs, data, spiffs, , 410K, coredump, data, coredump,, 64K, From 981895d3157df20b16a1c7eddba9d61e27277803 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Fri, 29 Nov 2024 01:22:07 +0100 Subject: [PATCH 15/32] Convert partition table to hex, update WebUI --- data | 2 +- partition.csv | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/data b/data index de99a22..f0fa58b 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit de99a221d688949da0d95e2f9df2da5ba77f5c0d +Subproject commit f0fa58b5ea60f695aeaae9ddd7138cbb3686e96a diff --git a/partition.csv b/partition.csv index 778b9f2..80714ea 100644 --- a/partition.csv +++ b/partition.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 36K, 20K, -otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 1760K, -app1, app, ota_1, , 1760K, -spiffs, data, spiffs, , 410K, -coredump, data, coredump,, 64K, +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x1b8000, +app1, app, ota_1, , 0x1b8000, +spiffs, data, spiffs, , 0x66800, +coredump, data, coredump,, 0x10000, \ No newline at end of file From 41b5fcf1c1938c4bac7e9cea53395c07e39ffaec Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 5 Dec 2024 04:32:32 +0100 Subject: [PATCH 16/32] Bugfix for suffix compact mode --- lib/btclock/data_handler.cpp | 9 +++++---- maintainers.yaml | 20 ++++++++++++++++++++ test/test_datahandler/test_main.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 maintainers.yaml diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index c1f1d1f..80e2328 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -90,10 +90,11 @@ std::array parsePriceData(std::uint32_t price, char cu firstIndex = 1; } - if (shareDot) + size_t dotPosition = priceString.find('.'); + + if (shareDot && dotPosition != std::string::npos && dotPosition > 0) { std::vector tempArray; - size_t dotPosition = priceString.find('.'); if (dotPosition != std::string::npos && dotPosition > 0) { for (size_t i = 0; i < priceString.length(); ++i) @@ -322,9 +323,9 @@ emscripten::val parseBlockHeightArray(std::uint32_t blockHeight) return arrayToStringArray(parseBlockHeight(blockHeight)); } -emscripten::val parsePriceDataArray(std::uint32_t price, const std::string ¤cySymbol, bool useSuffixFormat = false) +emscripten::val parsePriceDataArray(std::uint32_t price, const std::string ¤cySymbol, bool useSuffixFormat = false, bool mowMode = false, bool shareDot = false) { - return arrayToStringArray(parsePriceData(price, currencySymbol[0], useSuffixFormat)); + return arrayToStringArray(parsePriceData(price, currencySymbol[0], useSuffixFormat, mowMode, shareDot)); } emscripten::val parseHalvingCountdownArray(std::uint32_t blockHeight, bool asBlocks) diff --git a/maintainers.yaml b/maintainers.yaml new file mode 100644 index 0000000..8176c63 --- /dev/null +++ b/maintainers.yaml @@ -0,0 +1,20 @@ +identifier: BTClock +maintainers: +- npub1k5f85zx0xdskyayqpfpc0zq6n7vwqjuuxugkayk72fgynp34cs3qfcvqg2 +relays: +- wss://relay.noderunners.network/ +- wss://nostr.sathoarder.com/ +- wss://offchain.pub/ +- wss://nostr3.daedaluslabs.io/ +- wss://nostr4.daedaluslabs.io/ +- wss://nostr.dbtc.link/ +- wss://purplepag.es/ +- wss://nos.lol/ +- wss://nostr1.daedaluslabs.io/ +- wss://nostr.noderunners.network/ +- wss://nostr.lnbitcoin.cz/ +- wss://relay.primal.net/ +- wss://relay.damus.io +- wss://nostr-relay.derekross.me/ +- wss://nostr2.azzamo.net/ +- wss://nostr2.daedaluslabs.io/ diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index f2ad64c..6314f34 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -98,6 +98,30 @@ void test_PriceSuffixMode(void) TEST_ASSERT_EQUAL_STRING("K", output[NUM_SCREENS - 1].c_str()); } +void test_PriceSuffixModeCompact1(void) +{ + std::array output = parsePriceData(100000, '$', true, false, true); + TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); + + TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS - 5].c_str()); + TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 4].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); + TEST_ASSERT_EQUAL_STRING("K", output[NUM_SCREENS - 1].c_str()); +} + +void test_PriceSuffixModeCompact2(void) +{ + std::array output = parsePriceData(1000000, '$', true, false, true); + TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); + + TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS - 5].c_str()); + TEST_ASSERT_EQUAL_STRING("1.", output[NUM_SCREENS - 4].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); + TEST_ASSERT_EQUAL_STRING("M", output[NUM_SCREENS - 1].c_str()); +} + void test_PriceSuffixModeMow(void) { std::array output = parsePriceData(93000, '$', true, true); @@ -246,6 +270,8 @@ int runUnityTests(void) RUN_TEST(test_Mcap1TrillionJpy); RUN_TEST(test_Mcap1TrillionJpySmallChars); RUN_TEST(test_PriceSuffixMode); + RUN_TEST(test_PriceSuffixModeCompact1); + RUN_TEST(test_PriceSuffixModeCompact2); RUN_TEST(test_PriceSuffixModeMow); RUN_TEST(test_PriceSuffixModeMowCompact); From f0f591a16f7c5a9409be5cf83d9fa5d0476c9da6 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 5 Dec 2024 05:21:14 +0100 Subject: [PATCH 17/32] Make better use of the screens in compact suffix mode --- lib/btclock/data_handler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index 80e2328..60b0ef1 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -73,7 +73,8 @@ std::array parsePriceData(std::uint32_t price, char cu std::string priceString; if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat) { - priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, NUM_SCREENS - 2, mowMode); + int numScreens = shareDot && !mowMode ? NUM_SCREENS - 1 : NUM_SCREENS - 2; + priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, numScreens, mowMode); } else { From 33c06c86a1394a3a8e608b5e65f4755edf63e315 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 5 Dec 2024 18:22:59 +0100 Subject: [PATCH 18/32] Prepare sats per dollar for 1B amounts --- lib/btclock/data_handler.cpp | 21 +++++++++++-- test/test_datahandler/test_main.cpp | 47 +++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index 60b0ef1..b489bb8 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -139,9 +139,26 @@ std::array parseSatsPerCurrency(std::uint32_t price,ch if (priceString.length() < (NUM_SCREENS)) { - priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); + // Check if price is greater than 1 billion + if (price >= 100000000) + { + double satsPerCurrency = (1.0 / static_cast(price)) * 1e8; // Calculate satoshis + std::ostringstream oss; + oss << std::fixed << std::setprecision(3) << satsPerCurrency; // Format with 3 decimal places + priceString = oss.str(); + } + else + { + priceString = std::to_string(static_cast(round(1.0 / static_cast(price) * 1e8))); // Default formatting + } - if (currencySymbol != CURRENCY_USD) + // Pad the string with spaces if necessary + if (priceString.length() < NUM_SCREENS) + { + priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); + } + + if (currencySymbol != CURRENCY_USD || price >= 100000000) // no time anymore when earlier than 1 ret[0] = "SATS/" + getCurrencyCode(currencySymbol); else ret[0] = "MSCW/TIME"; diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index 6314f34..b09c9b1 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -33,6 +33,17 @@ void test_CorrectSatsPerDollarConversion(void) TEST_ASSERT_EQUAL_STRING("4", output[NUM_SCREENS - 1].c_str()); } +void test_SatsPerDollarAfter1B(void) +{ + std::array output = parseSatsPerCurrency(120000000, CURRENCY_USD, false); + TEST_ASSERT_EQUAL_STRING("SATS/USD", output[0].c_str()); + TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 5].c_str()); + TEST_ASSERT_EQUAL_STRING(".", output[NUM_SCREENS - 4].c_str()); + TEST_ASSERT_EQUAL_STRING("8", output[NUM_SCREENS - 3].c_str()); + TEST_ASSERT_EQUAL_STRING("3", output[NUM_SCREENS - 2].c_str()); + TEST_ASSERT_EQUAL_STRING("3", output[NUM_SCREENS - 1].c_str()); +} + void test_CorrectSatsPerPoundConversion(void) { std::array output = parseSatsPerCurrency(37253, CURRENCY_GBP, false); @@ -101,25 +112,33 @@ void test_PriceSuffixMode(void) void test_PriceSuffixModeCompact1(void) { std::array output = parsePriceData(100000, '$', true, false, true); - TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING("1", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("K", output[NUM_SCREENS - 1].c_str()); + std::string joined = joinArrayWithBrackets(output); + + TEST_ASSERT_EQUAL_STRING_MESSAGE("BTC/USD", output[0].c_str(), joined.c_str()); + + TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("1", output[NUM_SCREENS - 5].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0.", output[NUM_SCREENS - 3].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 2].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("K", output[NUM_SCREENS - 1].c_str(), joined.c_str()); } void test_PriceSuffixModeCompact2(void) { std::array output = parsePriceData(1000000, '$', true, false, true); - TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); - TEST_ASSERT_EQUAL_STRING("$", output[NUM_SCREENS - 5].c_str()); - TEST_ASSERT_EQUAL_STRING("1.", output[NUM_SCREENS - 4].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 3].c_str()); - TEST_ASSERT_EQUAL_STRING("0", output[NUM_SCREENS - 2].c_str()); - TEST_ASSERT_EQUAL_STRING("M", output[NUM_SCREENS - 1].c_str()); + std::string joined = joinArrayWithBrackets(output); + + TEST_ASSERT_EQUAL_STRING_MESSAGE("BTC/USD", output[0].c_str(), joined.c_str()); + + TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("1.", output[NUM_SCREENS - 5].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 3].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 2].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("M", output[NUM_SCREENS - 1].c_str(), joined.c_str()); } void test_PriceSuffixModeMow(void) @@ -143,7 +162,8 @@ void test_PriceSuffixModeMowCompact(void) std::string joined = joinArrayWithBrackets(output); - TEST_ASSERT_EQUAL_STRING("BTC/USD", output[0].c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("BTC/USD", output[0].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); TEST_ASSERT_EQUAL_STRING_MESSAGE("0.", output[NUM_SCREENS - 5].c_str(), joined.c_str()); TEST_ASSERT_EQUAL_STRING_MESSAGE("0", output[NUM_SCREENS - 4].c_str(), joined.c_str()); @@ -258,6 +278,7 @@ int runUnityTests(void) UNITY_BEGIN(); RUN_TEST(test_CorrectSatsPerDollarConversion); RUN_TEST(test_CorrectSatsPerPoundConversion); + RUN_TEST(test_SatsPerDollarAfter1B); RUN_TEST(test_SixCharacterBlockHeight); RUN_TEST(test_SevenCharacterBlockHeight); RUN_TEST(test_FeeRateDisplay); From d6604d28d66a4e8458a8f412fff5a13c92c2599a Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 5 Dec 2024 18:28:46 +0100 Subject: [PATCH 19/32] Update some initial values --- src/lib/block_notify.cpp | 2 +- src/lib/price_notify.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/block_notify.cpp b/src/lib/block_notify.cpp index b86d497..c4db06e 100644 --- a/src/lib/block_notify.cpp +++ b/src/lib/block_notify.cpp @@ -2,7 +2,7 @@ char *wsServer; esp_websocket_client_handle_t blockNotifyClient = NULL; -uint currentBlockHeight = 860000; +uint currentBlockHeight = 873400; uint blockMedianFee = 1; bool blockNotifyInit = false; unsigned long int lastBlockUpdate; diff --git a/src/lib/price_notify.cpp b/src/lib/price_notify.cpp index f995de8..ab5192b 100644 --- a/src/lib/price_notify.cpp +++ b/src/lib/price_notify.cpp @@ -8,7 +8,7 @@ const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin"; // WebsocketsClient client; esp_websocket_client_handle_t clientPrice = NULL; esp_websocket_client_config_t config; -uint currentPrice = 50000; +uint currentPrice = 90000; unsigned long int lastPriceUpdate; bool priceNotifyInit = false; std::map currencyMap; From 132aa835cd8492900b9af9bc89f6cd1e25ad4635 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Mon, 9 Dec 2024 15:58:39 -0600 Subject: [PATCH 20/32] Mow Units no rounding! --- lib/btclock/data_handler.cpp | 11 +++++++++-- lib/btclock/utils.cpp | 24 +++++++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/btclock/data_handler.cpp b/lib/btclock/data_handler.cpp index b489bb8..eaf4538 100644 --- a/lib/btclock/data_handler.cpp +++ b/lib/btclock/data_handler.cpp @@ -73,7 +73,7 @@ std::array parsePriceData(std::uint32_t price, char cu std::string priceString; if (std::to_string(price).length() >= NUM_SCREENS || useSuffixFormat) { - int numScreens = shareDot && !mowMode ? NUM_SCREENS - 1 : NUM_SCREENS - 2; + int numScreens = shareDot || mowMode ? NUM_SCREENS - 1 : NUM_SCREENS - 2; priceString = getCurrencySymbol(currencySymbol) + formatNumberWithSuffix(price, numScreens, mowMode); } else @@ -85,7 +85,14 @@ std::array parsePriceData(std::uint32_t price, char cu { priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); - ret[0] = "BTC/" + getCurrencyCode(currencySymbol); + if (mowMode) + { + ret[0] = "MOW/UNITS"; + } + else + { + ret[0] = "BTC/" + getCurrencyCode(currencySymbol); + } firstIndex = 1; diff --git a/lib/btclock/utils.cpp b/lib/btclock/utils.cpp index 9056d14..45dfdd2 100644 --- a/lib/btclock/utils.cpp +++ b/lib/btclock/utils.cpp @@ -1,4 +1,5 @@ #include "utils.hpp" +#include int modulo(int x, int N) { @@ -83,14 +84,31 @@ std::string formatNumberWithSuffix(std::uint64_t num, int numCharacters, bool mo } // Add suffix - int len = snprintf(result, sizeof(result), "%.0f%c", numDouble, suffix); + int len; + + // Mow Mode always uses string truncation to avoid rounding + std::string mowAsString = std::to_string(numDouble); + if (mowMode) { + // Default to one decimal place + len = snprintf(result, sizeof(result), "%s%c", mowAsString.substr(0, mowAsString.find(".") + 2).c_str(), suffix); + } + else + { + len = snprintf(result, sizeof(result), "%.0f%c", numDouble, suffix); + } // If there's room, add more decimal places if (len < numCharacters) { int restLen = mowMode ? numCharacters - len : numCharacters - len - 1; - - snprintf(result, sizeof(result), "%.*f%c", restLen, numDouble, suffix); + + if (mowMode) { + snprintf(result, sizeof(result), "%s%c", mowAsString.substr(0, mowAsString.find(".") + 2 + restLen).c_str(), suffix); + } + else + { + snprintf(result, sizeof(result), "%.*f%c", restLen, numDouble, suffix); + } } return result; From 9ada991ab15f7aa90060c8692da8554852617d7b Mon Sep 17 00:00:00 2001 From: kdmukai Date: Mon, 9 Dec 2024 16:05:55 -0600 Subject: [PATCH 21/32] Update utils.cpp --- lib/btclock/utils.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/btclock/utils.cpp b/lib/btclock/utils.cpp index 45dfdd2..0e19962 100644 --- a/lib/btclock/utils.cpp +++ b/lib/btclock/utils.cpp @@ -1,5 +1,4 @@ #include "utils.hpp" -#include int modulo(int x, int N) { From 2a116d97ed88333296949c6b84529bbb303827f3 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 10 Dec 2024 15:13:17 +0100 Subject: [PATCH 22/32] Add frontlight off when dark setting --- data | 2 +- src/lib/defaults.hpp | 2 ++ src/lib/webserver.cpp | 4 +++- src/main.cpp | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/data b/data index f0fa58b..25e91b2 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit f0fa58b5ea60f695aeaae9ddd7138cbb3686e96a +Subproject commit 25e91b2086936e7c6ef09e917c6efd371293fd7e diff --git a/src/lib/defaults.hpp b/src/lib/defaults.hpp index 8af3b5b..ada5531 100644 --- a/src/lib/defaults.hpp +++ b/src/lib/defaults.hpp @@ -45,6 +45,8 @@ #define DEFAULT_FL_EFFECT_DELAY 15 #define DEFAULT_LUX_LIGHT_TOGGLE 128 +#define DEFAULT_FL_OFF_WHEN_DARK true + #define DEFAULT_FL_ALWAYS_ON false #define DEFAULT_FL_FLASH_ON_UPDATE false diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index 777fe0b..b901379 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -546,7 +546,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) "mdnsEnabled", "otaEnabled", "stealFocus", "mcapBigChar", "useSatsSymbol", "useBlkCountdown", "suffixPrice", "disableLeds", "ownDataSource", - "mowMode", "suffixShareDot", + "mowMode", "suffixShareDot", "flOffWhenDark", "flAlwaysOn", "flDisable", "flFlashOnUpd", "mempoolSecure", "useNostr", "bitaxeEnabled", "nostrZapNotify", "stagingSource", "httpAuthEnabled"}; @@ -726,6 +726,8 @@ void onApiSettingsGet(AsyncWebServerRequest *request) root["hasLightLevel"] = hasLightLevel(); root["luxLightToggle"] = preferences.getUInt("luxLightToggle", DEFAULT_LUX_LIGHT_TOGGLE); + root["flOffWhenDark"] = preferences.getBool("flOffWhenDark", DEFAULT_FL_OFF_WHEN_DARK); + #else root["hasFrontlight"] = false; root["hasLightLevel"] = false; diff --git a/src/main.cpp b/src/main.cpp index 908f155..b9d2ae7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -51,7 +51,7 @@ extern "C" void app_main() if (hasLightLevel()) { if (preferences.getUInt("luxLightToggle", DEFAULT_LUX_LIGHT_TOGGLE) != 0) { - if (hasLightLevel() && getLightLevel() <= 2) + if (hasLightLevel() && getLightLevel() <= 1 && preferences.getBool("flOffWhenDark", DEFAULT_FL_OFF_WHEN_DARK)) { if (frontlightIsOn()) { frontlightFadeOutAll(); From dbf2c53083c05187d5e6f152d5e2ba32a3fd16a1 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Tue, 10 Dec 2024 15:18:04 +0100 Subject: [PATCH 23/32] Adapted tests for Mow Units --- test/test_datahandler/test_main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/test_datahandler/test_main.cpp b/test/test_datahandler/test_main.cpp index b09c9b1..24118e4 100644 --- a/test/test_datahandler/test_main.cpp +++ b/test/test_datahandler/test_main.cpp @@ -143,7 +143,7 @@ void test_PriceSuffixModeCompact2(void) void test_PriceSuffixModeMow(void) { - std::array output = parsePriceData(93000, '$', true, true); + std::array output = parsePriceData(93600, '$', true, true); std::string joined = joinArrayWithBrackets(output); @@ -158,11 +158,11 @@ void test_PriceSuffixModeMow(void) void test_PriceSuffixModeMowCompact(void) { - std::array output = parsePriceData(93000, '$', true, true, true); + std::array output = parsePriceData(93600, '$', true, true, true); std::string joined = joinArrayWithBrackets(output); - TEST_ASSERT_EQUAL_STRING_MESSAGE("BTC/USD", output[0].c_str(), joined.c_str()); + TEST_ASSERT_EQUAL_STRING_MESSAGE("MOW/UNITS", output[0].c_str(), joined.c_str()); TEST_ASSERT_EQUAL_STRING_MESSAGE("$", output[NUM_SCREENS - 6].c_str(), joined.c_str()); TEST_ASSERT_EQUAL_STRING_MESSAGE("0.", output[NUM_SCREENS - 5].c_str(), joined.c_str()); From 34b77ea1056e2d7fa8c3df0795b666c6b2d07d84 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Thu, 12 Dec 2024 23:12:59 +0100 Subject: [PATCH 24/32] Update WebUI --- data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data b/data index 25e91b2..653a39d 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 25e91b2086936e7c6ef09e917c6efd371293fd7e +Subproject commit 653a39d0a339bcf3ac3365eacd2e5e8136ecf4c6 From db0ec01c869bb2485308943a679b98a036272b05 Mon Sep 17 00:00:00 2001 From: kdmukai Date: Tue, 17 Dec 2024 08:53:00 -0600 Subject: [PATCH 25/32] Add bitaxe logo --- lib/btclock/bitaxe_handler.cpp | 4 +- src/icons/icons.cpp | 260 ++++++++++++++++++++++++++++++++- src/lib/epd.cpp | 6 +- 3 files changed, 264 insertions(+), 6 deletions(-) diff --git a/lib/btclock/bitaxe_handler.cpp b/lib/btclock/bitaxe_handler.cpp index cbc71ec..c18b7de 100644 --- a/lib/btclock/bitaxe_handler.cpp +++ b/lib/btclock/bitaxe_handler.cpp @@ -24,7 +24,7 @@ std::array parseBitaxeHashRate(std::string text) } ret[NUM_SCREENS - 1] = "GH/S"; - ret[0] = "BIT/AXE"; + ret[0] = "mdi:bitaxe"; return ret; } @@ -37,7 +37,7 @@ std::array parseBitaxeBestDiff(std::string text) if (text.length() < NUM_SCREENS) { text.insert(text.begin(), NUM_SCREENS - text.length(), ' '); - ret[0] = "BIT/AXE"; + ret[0] = "mdi:bitaxe"; ret[1] = "mdi:rocket"; firstIndex = 2; } diff --git a/src/icons/icons.cpp b/src/icons/icons.cpp index 3254740..ca69f63 100644 --- a/src/icons/icons.cpp +++ b/src/icons/icons.cpp @@ -1015,11 +1015,267 @@ const unsigned char epd_icons_flash [] PROGMEM = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 }; +// 'bitaxe_logo', 122x250px +const unsigned char epd_icons_bitaxe_logo [] PROGMEM = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xcf, 0xff, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xf0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xfc, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x03, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0x83, 0xff, 0xff, 0xf7, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xf1, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xf8, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xcf, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xe7, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xe7, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xf9, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x07, 0xf8, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0x80, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x0f, 0xe0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0xff, 0xff, 0x8f, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x8f, 0xf7, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xef, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe2, 0x00, 0x00, 0x01, 0x00, 0x00, 0x20, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x11, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x7f, 0xff, 0xbf, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xbf, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0x9f, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xfb, 0xf0, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xf7, 0xf8, 0x3f, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x01, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xf1, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0x83, 0xff, 0xff, 0xe0, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xef, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x3f, 0xff, 0xcf, 0xff, 0xff, 0x83, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfe, 0x0f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf8, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf8, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfe, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xbf, 0xff, 0x01, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x7f, 0xc1, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0xff, 0xf8, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xfc, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xf8, 0x00, 0xff, 0xff, 0xff, 0xe0, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x01, 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x03, 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x03, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xc0, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0x80, 0x07, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xff, 0xff, 0xff, 0x81, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xe0, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xf8, 0x01, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfc, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x03, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x07, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0xff, 0xfd, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xfb, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xcf, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x83, 0xff, 0xf3, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xe7, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0x8f, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xfe, 0x3f, 0xcf, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x3f, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x82, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0 +}; + + // Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 8032) -const int epd_icons_allArray_LEN = 4; +const int epd_icons_allArray_LEN = 5; const unsigned char* epd_icons_allArray[epd_icons_allArray_LEN] = { epd_icons_pickaxe, epd_icons_rocket_launch, epd_icons_lightning, - epd_icons_flash + epd_icons_flash, + epd_icons_bitaxe_logo }; diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index 1c04725..3ef06e6 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -603,10 +603,12 @@ void renderIcon(const uint dispNum, const String &text, bool partial) if (text.endsWith("rocket")) { iconIndex = 1; } - - if (text.endsWith("lnbolt")) { + else if (text.endsWith("lnbolt")) { iconIndex = 3; } + else if (text.endsWith("bitaxe")) { + iconIndex = 4; + } displays[dispNum].drawInvertedBitmap(0,0, epd_icons_allArray[iconIndex], 122, 250, getFgColor()); From 4a52fc0bf22c050a440eca7aa885cf18bcd42f10 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 00:50:20 +0100 Subject: [PATCH 26/32] Add vertical screen description option --- data | 2 +- src/lib/defaults.hpp | 1 + src/lib/epd.cpp | 6 +++++- src/lib/webserver.cpp | 3 +++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/data b/data index 653a39d..266a99b 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 653a39d0a339bcf3ac3365eacd2e5e8136ecf4c6 +Subproject commit 266a99be96189bea92e0ef593f930bb92d3b5b20 diff --git a/src/lib/defaults.hpp b/src/lib/defaults.hpp index ada5531..11df69a 100644 --- a/src/lib/defaults.hpp +++ b/src/lib/defaults.hpp @@ -70,3 +70,4 @@ #define DEFAULT_ACTIVE_CURRENCIES "USD,EUR,JPY" #define DEFAULT_GIT_RELEASE_URL "https://git.btclock.dev/api/v1/repos/btclock/btclock_v3/releases/latest" +#define DEFAULT_VERTICAL_DESC true diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index 1c04725..986b9cc 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -373,7 +373,11 @@ extern "C" void updateDisplay(void *pvParameters) noexcept void splitText(const uint dispNum, const String &top, const String &bottom, bool partial) { - displays[dispNum].setRotation(2); + if(preferences.getBool("verticalDesc", DEFAULT_VERTICAL_DESC) && dispNum == 0) { + displays[dispNum].setRotation(1); + } else { + displays[dispNum].setRotation(2); + } displays[dispNum].setFont(&FONT_SMALL); displays[dispNum].setTextColor(getFgColor()); diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index b901379..11b9024 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -549,6 +549,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json) "mowMode", "suffixShareDot", "flOffWhenDark", "flAlwaysOn", "flDisable", "flFlashOnUpd", "mempoolSecure", "useNostr", "bitaxeEnabled", + "verticalDesc", "nostrZapNotify", "stagingSource", "httpAuthEnabled"}; for (String setting : boolSettings) @@ -689,6 +690,8 @@ void onApiSettingsGet(AsyncWebServerRequest *request) root["suffixPrice"] = preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE); root["disableLeds"] = preferences.getBool("disableLeds", DEFAULT_DISABLE_LEDS); root["mowMode"] = preferences.getBool("mowMode", DEFAULT_MOW_MODE); + root["verticalDesc"] = preferences.getBool("verticalDesc", DEFAULT_VERTICAL_DESC); + root["suffixShareDot"] = preferences.getBool("suffixShareDot", DEFAULT_SUFFIX_SHARE_DOT); root["hostnamePrefix"] = preferences.getString("hostnamePrefix", DEFAULT_HOSTNAME_PREFIX); From 83d293c58e46f7698fd484bda35c7130a568014c Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 01:32:11 +0100 Subject: [PATCH 27/32] Add bitaxe logo to WebUI --- data | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data b/data index 266a99b..85b9b17 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 266a99be96189bea92e0ef593f930bb92d3b5b20 +Subproject commit 85b9b17506f89696b89ab6f6e6ed231b7a8f6e91 From af4c46665912b444bdaa056bbab6c060a767220e Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 19:47:03 +0100 Subject: [PATCH 28/32] Switch to leaner MCP23017 library, create new aligned partition tables --- .forgejo/workflows/push.yaml | 26 +++++++++++++------ partition.csv | 4 +-- partition_16mb.csv | 12 ++++----- partition_8mb.csv | 12 ++++----- platformio.ini | 14 +++++------ scripts/pre_script.py | 7 ++++++ src/lib/button_handler.cpp | 23 ++++++++--------- src/lib/config.cpp | 48 ++++++++++++++++++++++++++---------- src/lib/config.hpp | 6 +++-- src/lib/epd.cpp | 11 ++++++++- src/lib/epd.hpp | 1 + src/lib/shared.cpp | 10 +++++++- src/lib/shared.hpp | 12 ++++++--- 13 files changed, 127 insertions(+), 59 deletions(-) create mode 100644 scripts/pre_script.py diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 5121d24..6ccb926 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -95,7 +95,6 @@ jobs: - name: Create merged firmware binary run: | if [ "${{ matrix.chip.name }}" == "btclock_v8" ]; then - mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ esptool.py --chip ${{ matrix.chip.version }} merge_bin \ -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ --flash_mode dio \ @@ -105,7 +104,19 @@ jobs: 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x810000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin; + 0xDF0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_16MB.bin + elif [ "${{ matrix.chip.name }}" == "btclock_rev_b" ]; then + mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ + esptool.py --chip ${{ matrix.chip.version }} merge_bin \ + -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ + --flash_mode dio \ + --flash_freq 80m \ + --flash_size 8MB \ + 0x0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/bootloader.bin \ + 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ + 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ + 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ + 0x6F0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_8MB.bin; else # Original command for other cases mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ @@ -116,7 +127,7 @@ jobs: 0x8000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/partitions.bin \ 0xe000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/ota_data_initial.bin \ 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ - 0x370000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin + 0x380000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_4MB.bin # Adjust the offset for littlefs or other files as needed for the original case fi @@ -127,10 +138,11 @@ jobs: run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin.sha256 - name: Create checksum for littlefs partition - run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin.sha256 - - - name: Copy all artifacts to output folder - run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} + run: | + fs_file=$(find .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }} -name "littlefs*.bin") + shasum -a 256 "$fs_file" | awk '{print $1}' > "${fs_file}.sha256" + - name: Copy all artifacts to output folder + run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} - name: Create OTA binary file run: mv ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin diff --git a/partition.csv b/partition.csv index 80714ea..eedbf5b 100644 --- a/partition.csv +++ b/partition.csv @@ -3,5 +3,5 @@ nvs, data, nvs, 0x9000, 0x5000, otadata, data, ota, 0xe000, 0x2000, app0, app, ota_0, 0x10000, 0x1b8000, app1, app, ota_1, , 0x1b8000, -spiffs, data, spiffs, , 0x66800, -coredump, data, coredump,, 0x10000, \ No newline at end of file +spiffs, data, spiffs, , 0x66C00, +coredump, data, coredump,, 0x10000, diff --git a/partition_16mb.csv b/partition_16mb.csv index e26e145..7e58611 100644 --- a/partition_16mb.csv +++ b/partition_16mb.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 36K, 20K, -otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 4096K, -app1, app, ota_1, , 4096K, -spiffs, data, spiffs, , 410K, -coredump, data, coredump,, 64K, +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x6F0000, +app1, app, ota_1, , 0x6F0000, +spiffs, data, spiffs, , 0x200000, +coredump, data, coredump,, 0x10000, \ No newline at end of file diff --git a/partition_8mb.csv b/partition_8mb.csv index 778b9f2..025f649 100644 --- a/partition_8mb.csv +++ b/partition_8mb.csv @@ -1,7 +1,7 @@ # Name, Type, SubType, Offset, Size, Flags -nvs, data, nvs, 36K, 20K, -otadata, data, ota, 56K, 8K, -app0, app, ota_0, 64K, 1760K, -app1, app, ota_1, , 1760K, -spiffs, data, spiffs, , 410K, -coredump, data, coredump,, 64K, +nvs, data, nvs, 0x9000, 0x5000, +otadata, data, ota, 0xe000, 0x2000, +app0, app, ota_0, 0x10000, 0x370000, +app1, app, ota_1, , 0x370000, +spiffs, data, spiffs, , 0xCD000, +coredump, data, coredump,, 0x10000, \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 7b0d229..d2abb92 100644 --- a/platformio.ini +++ b/platformio.ini @@ -20,8 +20,9 @@ framework = arduino, espidf monitor_speed = 115200 monitor_filters = esp32_exception_decoder, colorize board_build.filesystem = littlefs -extra_scripts = post:scripts/extra_script.py -board_build.embed_files = x509_crt_bundle +extra_scripts = pre:scripts/pre_script.py, post:scripts/extra_script.py +board_build.embed_files = + x509_crt_bundle build_flags = !python scripts/git_rev.py -DLAST_BUILD_TIME=$UNIX_TIME @@ -35,14 +36,13 @@ lib_deps = https://github.com/joltwallet/esp_littlefs.git bblanchon/ArduinoJson@^7.2.1 mathieucarbou/ESPAsyncWebServer @ 3.3.23 - adafruit/Adafruit BusIO@^1.16.2 - adafruit/Adafruit MCP23017 Arduino Library@^2.3.2 + robtillaart/MCP23017@^0.8.0 adafruit/Adafruit NeoPixel@^1.12.3 - https://github.com/dsbaars/universal_pin + https://github.com/dsbaars/universal_pin#feature/mcp23017_rt https://github.com/dsbaars/GxEPD2#universal_pin https://github.com/tzapu/WiFiManager.git#v2.0.17 rblb/Nostrduino@1.2.8 - + [env:lolin_s3_mini] extends = btclock_base board = lolin_s3_mini @@ -64,7 +64,7 @@ build_unflags = [env:btclock_rev_b] extends = btclock_base board = btclock_rev_b -board_build.partitions = partition.csv +board_build.partitions = partition_8mb.csv build_flags = ${btclock_base.build_flags} -D MCP_INT_PIN=8 diff --git a/scripts/pre_script.py b/scripts/pre_script.py new file mode 100644 index 0000000..45d6bea --- /dev/null +++ b/scripts/pre_script.py @@ -0,0 +1,7 @@ +Import("env") + +flash_size = env.BoardConfig().get("upload.flash_size", "4MB") +fs_image_name = f"littlefs_{flash_size}" +env.Replace(ESP32_FS_IMAGE_NAME=fs_image_name) +env.Replace(ESP8266_FS_IMAGE_NAME=fs_image_name) + diff --git a/src/lib/button_handler.cpp b/src/lib/button_handler.cpp index 437090d..72f1eaa 100644 --- a/src/lib/button_handler.cpp +++ b/src/lib/button_handler.cpp @@ -5,15 +5,15 @@ const TickType_t debounceDelay = pdMS_TO_TICKS(50); TickType_t lastDebounceTime = 0; #ifdef IS_BTCLOCK_V8 -#define BTN_1 0 -#define BTN_2 1 -#define BTN_3 2 -#define BTN_4 3 +#define BTN_1 256 +#define BTN_2 512 +#define BTN_3 1024 +#define BTN_4 2048 #else -#define BTN_1 3 -#define BTN_2 2 -#define BTN_3 1 -#define BTN_4 0 +#define BTN_1 2048 +#define BTN_2 1024 +#define BTN_3 512 +#define BTN_4 256 #endif void buttonTask(void *parameter) { @@ -22,11 +22,12 @@ void buttonTask(void *parameter) { std::lock_guard lock(mcpMutex); TickType_t currentTime = xTaskGetTickCount(); + if ((currentTime - lastDebounceTime) >= debounceDelay) { lastDebounceTime = currentTime; if (!digitalRead(MCP_INT_PIN)) { - uint pin = mcp1.getLastInterruptPin(); + uint pin = mcp1.getInterruptFlagRegister(); switch (pin) { case BTN_1: @@ -43,12 +44,12 @@ void buttonTask(void *parameter) { break; } } - mcp1.clearInterrupts(); + mcp1.getInterruptCaptureRegister(); } else { } // Very ugly, but for some reason this is necessary while (!digitalRead(MCP_INT_PIN)) { - mcp1.clearInterrupts(); + mcp1.getInterruptCaptureRegister(); } } } diff --git a/src/lib/config.cpp b/src/lib/config.cpp index 8f954b2..e9912a9 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -2,10 +2,12 @@ #define MAX_ATTEMPTS_WIFI_CONNECTION 20 +// zlib_turbo zt; + Preferences preferences; -Adafruit_MCP23X17 mcp1; +MCP23017 mcp1(0x20); #ifdef IS_BTCLOCK_V8 -Adafruit_MCP23X17 mcp2; +MCP23017 mcp2(0x21); #endif #ifdef HAS_FRONTLIGHT @@ -35,7 +37,7 @@ void setup() } { std::lock_guard lockMcp(mcpMutex); - if (mcp1.digitalRead(3) == LOW) + if (mcp1.read1(3) == LOW) { preferences.putBool("wifiConfigured", false); preferences.remove("txPower"); @@ -46,7 +48,7 @@ void setup() } { - if (mcp1.digitalRead(0) == LOW) + if (mcp1.read1(0) == LOW) { // Then loop forever to prevent anything else from writing to the screen while (true) @@ -54,7 +56,7 @@ void setup() delay(1000); } } - else if (mcp1.digitalRead(1) == LOW) + else if (mcp1.read1(1) == LOW) { preferences.clear(); queueLedEffect(LED_EFFECT_WIFI_ERASE_SETTINGS); @@ -66,6 +68,7 @@ void setup() } setupWifi(); + // loadIcons(); setupWebserver(); @@ -106,6 +109,7 @@ void setup() #endif forceFullRefresh(); + } void setupWifi() @@ -132,7 +136,7 @@ void setupWifi() bool buttonPress = false; { std::lock_guard lockMcp(mcpMutex); - buttonPress = (mcp1.digitalRead(2) == LOW); + buttonPress = (mcp1.read1(2) == LOW); } { @@ -507,7 +511,7 @@ void setupHardware() Wire.begin(I2C_SDA_PIN, I2C_SCK_PIN, 400000); - if (!mcp1.begin_I2C(0x20)) + if (!mcp1.begin()) { Serial.println(F("Error MCP23017 1")); @@ -517,17 +521,20 @@ void setupHardware() else { pinMode(MCP_INT_PIN, INPUT_PULLUP); - mcp1.setupInterrupts(false, false, LOW); +// mcp1.setupInterrupts(false, false, LOW); + mcp1.enableControlRegister(MCP23x17_IOCR_ODR); + + mcp1.mirrorInterrupts(true); for (int i = 0; i < 4; i++) { - mcp1.pinMode(i, INPUT_PULLUP); - mcp1.setupInterruptPin(i, LOW); + mcp1.pinMode1(i, INPUT_PULLUP); + mcp1.enableInterrupt(i, LOW); } #ifndef IS_BTCLOCK_V8 for (int i = 8; i <= 14; i++) { - mcp1.pinMode(i, OUTPUT); + mcp1.pinMode1(i, OUTPUT); } #endif } @@ -538,7 +545,7 @@ void setupHardware() #endif #ifdef IS_BTCLOCK_V8 - if (!mcp2.begin_I2C(0x21)) + if (!mcp2.begin()) { Serial.println(F("Error MCP23017 2")); @@ -790,4 +797,19 @@ const char* getFirmwareFilename() { } else { return ""; } -} \ No newline at end of file +} + +// void loadIcons() { +// size_t ocean_logo_size = 886; + +// int iUncompSize = zt.gzip_info((uint8_t *)epd_compress_bitaxe, ocean_logo_size); +// Serial.printf("uncompressed size = %d\n", iUncompSize); + +// uint8_t *pUncompressed; +// pUncompressed = (uint8_t *)malloc(iUncompSize+4); +// int rc = zt.gunzip((uint8_t *)epd_compress_bitaxe, ocean_logo_size, pUncompressed); + +// if (rc == ZT_SUCCESS) { +// Serial.println("Decode success"); +// } +// } \ No newline at end of file diff --git a/src/lib/config.hpp b/src/lib/config.hpp index 8c9da90..53abe17 100644 --- a/src/lib/config.hpp +++ b/src/lib/config.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -83,4 +83,6 @@ void addScreenMapping(int value, const char* name); int findScreenIndexByValue(int value); String replaceAmbiguousChars(String input); -const char* getFirmwareFilename(); \ No newline at end of file +const char* getFirmwareFilename(); + +// void loadIcons(); \ No newline at end of file diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index 1e27eae..2b30f26 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -191,7 +191,7 @@ void setupDisplays() } // Hold lower button to enable "storage mode" (prevents burn-in of ePaper displays) - if (mcp1.digitalRead(0) == LOW) + if (mcp1.read1(0) == LOW) { setFgColor(GxEPD_BLACK); setBgColor(GxEPD_WHITE); @@ -614,10 +614,19 @@ void renderIcon(const uint dispNum, const String &text, bool partial) iconIndex = 4; } + + + displays[dispNum].drawInvertedBitmap(0,0, epd_icons_allArray[iconIndex], 122, 250, getFgColor()); + +// displays[dispNum].drawInvertedBitmap(0,0, getOceanIcon(), 122, 250, getFgColor()); + + } + + void renderQr(const uint dispNum, const String &text, bool partial) { #ifdef USE_QR diff --git a/src/lib/epd.hpp b/src/lib/epd.hpp index 749f940..1194cf1 100644 --- a/src/lib/epd.hpp +++ b/src/lib/epd.hpp @@ -4,6 +4,7 @@ #include #include + #include #include #include diff --git a/src/lib/shared.cpp b/src/lib/shared.cpp index 20bf6d4..3422ff8 100644 --- a/src/lib/shared.cpp +++ b/src/lib/shared.cpp @@ -143,4 +143,12 @@ String calculateSHA256(WiFiClient *stream, size_t contentLength) { } return result; -} \ No newline at end of file +} + +// uint8_t* getOceanIcon() { +// zlib_turbo zt; +// int iUncompSize = zt.gzip_info((uint8_t *)ocean_logo_comp, ocean_logo_size); +// uint8_t *pUncompressed; +// pUncompressed = (uint8_t *)malloc(iUncompSize+4); +// zt.gunzip((uint8_t *)ocean_logo_comp, ocean_logo_size, pUncompressed); +// } \ No newline at end of file diff --git a/src/lib/shared.hpp b/src/lib/shared.hpp index 19d1df0..4753764 100644 --- a/src/lib/shared.hpp +++ b/src/lib/shared.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include "MCP23017.h" +// #include #include #include #include @@ -17,9 +18,9 @@ #include "defaults.hpp" -extern Adafruit_MCP23X17 mcp1; +extern MCP23017 mcp1; #ifdef IS_BTCLOCK_V8 -extern Adafruit_MCP23X17 mcp2; +extern MCP23017 mcp2; #endif extern Preferences preferences; extern std::mutex mcpMutex; @@ -73,7 +74,12 @@ const int usPerMinute = 60 * usPerSecond; extern const char *isrg_root_x1cert; extern const uint8_t rootca_crt_bundle_start[] asm("_binary_x509_crt_bundle_start"); +// extern const uint8_t ocean_logo_comp[] asm("_binary_ocean_gz_start"); +// extern const uint8_t ocean_logo_comp_end[] asm("_binary_ocean_gz_end"); +// uint8_t* getOceanIcon(); + +// const size_t ocean_logo_size = ocean_logo_comp_end - ocean_logo_comp; const PROGMEM char UPDATE_FIRMWARE = U_FLASH; const PROGMEM char UPDATE_WEBUI = U_SPIFFS; From de8fe2e26eed61918f8133c614860a26d6291f9a Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 20:41:42 +0100 Subject: [PATCH 29/32] Fix preaction script --- scripts/extra_script.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/extra_script.py b/scripts/extra_script.py index d7e4b31..8451978 100644 --- a/scripts/extra_script.py +++ b/scripts/extra_script.py @@ -5,6 +5,9 @@ from shutil import copyfileobj, rmtree from pathlib import Path import subprocess + + + revision = ( subprocess.check_output(["git", "rev-parse", "HEAD"]) .strip() @@ -43,5 +46,15 @@ def before_buildfs(source, target, env): output_directory = 'data/build_gz' process_directory(input_directory, output_directory) +flash_size = env.BoardConfig().get("upload.flash_size", "4MB") +fs_image_name = f"littlefs_{flash_size}" +env.Replace(ESP32_FS_IMAGE_NAME=fs_image_name) +env.Replace(ESP8266_FS_IMAGE_NAME=fs_image_name) + os.environ["PUBLIC_BASE_URL"] = "" -env.AddPreAction("$BUILD_DIR/littlefs.bin", before_buildfs) +fs_name = env.get("ESP32_FS_IMAGE_NAME", "littlefs.bin") +# Or alternatively: +# fs_name = env.get("FSTOOLNAME", "littlefs.bin") + +# Use the variable in the pre-action +env.AddPreAction(f"$BUILD_DIR/{fs_name}.bin", before_buildfs) From 0dcde59fb4e2d3ac939886689b23e9b2c77b1ab1 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 21:40:18 +0100 Subject: [PATCH 30/32] Fix workflow --- .forgejo/workflows/push.yaml | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 6ccb926..02458ae 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -1,4 +1,4 @@ -name: 'BTClock CI' +name: "BTClock CI" on: push: @@ -22,7 +22,7 @@ jobs: with: node-version: lts/* cache: yarn - cache-dependency-path: '**/yarn.lock' + cache-dependency-path: "**/yarn.lock" - uses: actions/cache@v4 with: path: | @@ -34,8 +34,8 @@ jobs: key: ${{ runner.os }}-pio - uses: actions/setup-python@v5 with: - python-version: '3.9' - cache: 'pip' + python-version: "3.9" + cache: "pip" - name: Get current date id: dateAndTime shell: bash @@ -48,7 +48,7 @@ jobs: run: mkdir -p junit-reports && pio test -e native_test_only --junit-output-path junit-reports/ - name: Build BTClock firmware shell: bash - run: pio run + run: pio run - name: Build BTClock filesystem shell: bash run: pio run --target buildfs @@ -81,9 +81,9 @@ jobs: version: esp32s3 epd_variant: [213epd, 29epd] exclude: - - chip: {name: btclock_rev_b, version: esp32s3} + - chip: { name: btclock_rev_b, version: esp32s3 } epd_variant: 29epd - - chip: {name: btclock_v8, version: esp32s3} + - chip: { name: btclock_v8, version: esp32s3 } epd_variant: 29epd steps: - uses: https://code.forgejo.org/forgejo/download-artifact@v4 @@ -93,7 +93,9 @@ jobs: - name: Install esptools.py run: pip install --upgrade esptool - name: Create merged firmware binary + shell: bash run: | + mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} if [ "${{ matrix.chip.name }}" == "btclock_v8" ]; then esptool.py --chip ${{ matrix.chip.version }} merge_bin \ -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ @@ -106,7 +108,6 @@ jobs: 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ 0xDF0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_16MB.bin elif [ "${{ matrix.chip.name }}" == "btclock_rev_b" ]; then - mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ esptool.py --chip ${{ matrix.chip.version }} merge_bin \ -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ --flash_mode dio \ @@ -118,8 +119,6 @@ jobs: 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin \ 0x6F0000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs_8MB.bin; else - # Original command for other cases - mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && \ esptool.py --chip ${{ matrix.chip.version }} merge_bin \ -o ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin \ --flash_mode dio \ @@ -132,17 +131,20 @@ jobs: fi - name: Create checksum for firmware + shell: bash run: shasum -a 256 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin.sha256 - name: Create checksum for merged binary + shell: bash run: shasum -a 256 ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin | awk '{print $1}' > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}.bin.sha256 - name: Create checksum for littlefs partition + shell: bash run: | fs_file=$(find .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }} -name "littlefs*.bin") shasum -a 256 "$fs_file" | awk '{print $1}' > "${fs_file}.sha256" - - name: Copy all artifacts to output folder - run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} + - name: Copy all artifacts to output folder + run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} - name: Create OTA binary file run: mv ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${{ matrix.chip.name }}_${{ matrix.epd_variant }}_firmware.bin @@ -173,13 +175,13 @@ jobs: - name: Create release uses: https://code.forgejo.org/actions/forgejo-release@v2.4.0 with: - url: 'https://git.btclock.dev' - repo: '${{ github.repository }}' + url: "https://git.btclock.dev" + repo: "${{ github.repository }}" direction: upload - tag: '${{ github.ref_name }}' - sha: '${{ github.sha }}' + tag: "${{ github.ref_name }}" + sha: "${{ github.sha }}" release-dir: release token: ${{ secrets.TOKEN }} override: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} prerelease: ${{ github.ref_type != 'tag' && github.ref_name != 'main' }} - release-notes-assistant: false \ No newline at end of file + release-notes-assistant: false From c989169ff46581785e10132db04d980264713571 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 22:20:40 +0100 Subject: [PATCH 31/32] Fix workflow and auto updater webui filenames --- .forgejo/workflows/push.yaml | 2 +- src/lib/config.cpp | 13 +++++++++++++ src/lib/config.hpp | 2 +- src/lib/ota.cpp | 3 +-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index 02458ae..b95439c 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -142,7 +142,7 @@ jobs: shell: bash run: | fs_file=$(find .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }} -name "littlefs*.bin") - shasum -a 256 "$fs_file" | awk '{print $1}' > "${fs_file}.sha256" + shasum -a 256 "$fs_file" | awk '{print $1}' > "${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${fs_file}.sha256" - name: Copy all artifacts to output folder run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }} diff --git a/src/lib/config.cpp b/src/lib/config.cpp index e9912a9..1dac009 100644 --- a/src/lib/config.cpp +++ b/src/lib/config.cpp @@ -799,6 +799,19 @@ const char* getFirmwareFilename() { } } +const char* getWebUiFilename() { + if (HW_REV == "REV_B_EPD_2_13") { + return "littlefs_8MB.bin"; + } else if (HW_REV == "REV_A_EPD_2_13") { + return "littlefs_4MB.bin"; + } else if (HW_REV == "REV_A_EPD_2_9") { + return "littlefs_4MB.bin"; + } else { + return "littlefs_4MB.bin"; + } +} + + // void loadIcons() { // size_t ocean_logo_size = 886; diff --git a/src/lib/config.hpp b/src/lib/config.hpp index 53abe17..51aef87 100644 --- a/src/lib/config.hpp +++ b/src/lib/config.hpp @@ -84,5 +84,5 @@ void addScreenMapping(int value, const char* name); int findScreenIndexByValue(int value); String replaceAmbiguousChars(String input); const char* getFirmwareFilename(); - +const char* getWebUiFilename(); // void loadIcons(); \ No newline at end of file diff --git a/src/lib/ota.cpp b/src/lib/ota.cpp index 1800f76..05c45e1 100644 --- a/src/lib/ota.cpp +++ b/src/lib/ota.cpp @@ -171,14 +171,13 @@ int downloadUpdateHandler(char updateType) break; case UPDATE_WEBUI: { - latestRelease = getLatestRelease("littlefs.bin"); + latestRelease = getLatestRelease(getWebUiFilename()); // updateWebUi(latestRelease.fileUrl, U_SPIFFS); // return 0; } break; } - // First, download the expected SHA256 String expectedSHA256 = downloadSHA256(latestRelease.checksumUrl); if (expectedSHA256.isEmpty()) From ae2e6656dfaef3cf762c86057b3716871b0fb850 Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 18 Dec 2024 22:52:50 +0100 Subject: [PATCH 32/32] Fix LittleFS sha256 generation --- .forgejo/workflows/push.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.forgejo/workflows/push.yaml b/.forgejo/workflows/push.yaml index b95439c..219205f 100644 --- a/.forgejo/workflows/push.yaml +++ b/.forgejo/workflows/push.yaml @@ -142,7 +142,10 @@ jobs: shell: bash run: | fs_file=$(find .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }} -name "littlefs*.bin") - shasum -a 256 "$fs_file" | awk '{print $1}' > "${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${fs_file}.sha256" + echo $fs_file + fs_name=$(basename "$fs_file") + shasum -a 256 "$fs_file" | awk '{print $1}' > "${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${fs_name}.sha256" + cat "${{ matrix.chip.name }}_${{ matrix.epd_variant }}/${fs_name}.sha256" - name: Copy all artifacts to output folder run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin .pio/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}