Add GitHub workflow and S3 mini targets
This commit is contained in:
parent
dbf7cc46d1
commit
082d61c84e
11 changed files with 262 additions and 25 deletions
43
.github/actions/install-build/action.yml
vendored
Normal file
43
.github/actions/install-build/action.yml
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
name: "Install and build"
|
||||||
|
description: "Install and build"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: lts/*
|
||||||
|
cache: yarn
|
||||||
|
cache-dependency-path: '**/yarn.lock'
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cache/pip
|
||||||
|
~/.platformio/.cache
|
||||||
|
~/data/node_modules
|
||||||
|
key: ${{ runner.os }}-pio
|
||||||
|
- uses: actions/setup-python@v4
|
||||||
|
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
|
19
.github/workflows/pull_request.yml
vendored
Normal file
19
.github/workflows/pull_request.yml
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
name: Pull Request Workflow
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
checks: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: "Install and build"
|
||||||
|
uses: ./.github/actions/install-build
|
71
.github/workflows/tagging.yml
vendored
Normal file
71
.github/workflows/tagging.yml
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
name: BTClock CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
epd_variant: [213epd, 29epd]
|
||||||
|
chip:
|
||||||
|
- name: lolin_s2_mini
|
||||||
|
version: esp32s2
|
||||||
|
# chips:
|
||||||
|
# - name: lolin_s3_mini
|
||||||
|
# version: esp32s3
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
checks: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: "Install and build"
|
||||||
|
uses: ./.github/actions/install-build
|
||||||
|
|
||||||
|
- name: Install esptools.py
|
||||||
|
run: pip install --upgrade esptool
|
||||||
|
|
||||||
|
- name: Create merged firmware binary
|
||||||
|
run: mkdir -p ${{ matrix.chip.name }}_${{ matrix.epd_variant }} && esptool.py --chip ${{ matrix.chips.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 ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin 0x10000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/firmware.bin 0x369000 .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/littlefs.bin
|
||||||
|
|
||||||
|
- 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 }}.sha256
|
||||||
|
|
||||||
|
# - name: Write commit hash to file
|
||||||
|
# run: echo $GITHUB_SHA > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/commit.txt
|
||||||
|
|
||||||
|
# - name: Write build date to file
|
||||||
|
# run: echo "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" > ${{ matrix.chip.name }}_${{ matrix.epd_variant }}/date.txt
|
||||||
|
|
||||||
|
# - name: Copy all artifacts to output folder
|
||||||
|
# run: cp .pio/build/${{ matrix.chip.name }}_${{ matrix.epd_variant }}/*.bin ~/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin ${{ matrix.chip.name }}_${{ matrix.epd_variant }}
|
||||||
|
|
||||||
|
- name: Upload artifacts
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
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: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
checks: write
|
||||||
|
needs: build
|
||||||
|
- name: Download matrix outputs
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build-*
|
||||||
|
- name: Create release
|
||||||
|
uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
artifacts: "*/*.bin,*/*.sha256"
|
||||||
|
allowUpdates: true
|
||||||
|
removeArtifacts: true
|
||||||
|
makeLatest: true
|
|
@ -2,7 +2,7 @@
|
||||||
;
|
;
|
||||||
; Build options: build flags, source filter
|
; Build options: build flags, source filter
|
||||||
; Upload options: custom upload port, speed and extra flags
|
; Upload options: custom upload port, speed and extra flags
|
||||||
; Library options: dependencies, extra library storages
|
; Library options: dependencies, extra library storages tl
|
||||||
; Advanced options: extra scripting
|
; Advanced options: extra scripting
|
||||||
;
|
;
|
||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
data_dir = data/build
|
data_dir = data/build
|
||||||
|
default_envs = lolin_s2_mini_213epd, lolin_s2_mini_29epd, lolin_s3_mini_213epd
|
||||||
|
|
||||||
[btclock_base]
|
[btclock_base]
|
||||||
platform = espressif32
|
platform = espressif32
|
||||||
|
@ -30,16 +31,30 @@ lib_deps =
|
||||||
extends = btclock_base
|
extends = btclock_base
|
||||||
board = lolin_s2_mini
|
board = lolin_s2_mini
|
||||||
|
|
||||||
|
[env:lolin_s3_mini]
|
||||||
|
extends = btclock_base
|
||||||
|
board = lolin_s3_mini
|
||||||
|
|
||||||
[env:lolin_s2_mini_213epd]
|
[env:lolin_s2_mini_213epd]
|
||||||
extends = env:lolin_s2_mini
|
extends = env:lolin_s2_mini
|
||||||
board = lolin_s2_mini
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${btclock_base.build_flags}
|
${btclock_base.build_flags}
|
||||||
-D VERSION_EPD_2_13
|
-D VERSION_EPD_2_13
|
||||||
|
|
||||||
[env:lolin_s2_mini_29epd]
|
[env:lolin_s2_mini_29epd]
|
||||||
extends = env:lolin_s2_mini
|
extends = env:lolin_s2_mini
|
||||||
board = lolin_s2_mini
|
build_flags =
|
||||||
|
${btclock_base.build_flags}
|
||||||
|
-D VERSION_EPD_2_9
|
||||||
|
|
||||||
|
[env:lolin_s3_mini_213epd]
|
||||||
|
extends = env:lolin_s3_mini
|
||||||
|
build_flags =
|
||||||
|
${btclock_base.build_flags}
|
||||||
|
-D VERSION_EPD_2_13
|
||||||
|
|
||||||
|
[env:lolin_s3_mini_29epd]
|
||||||
|
extends = env:lolin_s3_mini
|
||||||
build_flags =
|
build_flags =
|
||||||
${btclock_base.build_flags}
|
${btclock_base.build_flags}
|
||||||
-D VERSION_EPD_2_9
|
-D VERSION_EPD_2_9
|
|
@ -19,6 +19,24 @@ void setupTime()
|
||||||
void setupPreferences()
|
void setupPreferences()
|
||||||
{
|
{
|
||||||
preferences.begin("btclock", false);
|
preferences.begin("btclock", false);
|
||||||
|
|
||||||
|
if (!preferences.isKey(SETTING_ROW1_CONTENT))
|
||||||
|
{
|
||||||
|
preferences.putUInt(SETTING_ROW1_CONTENT, LINE_BLOCKHEIGHT);
|
||||||
|
}
|
||||||
|
if (!preferences.isKey(SETTING_ROW2_CONTENT))
|
||||||
|
{
|
||||||
|
preferences.putUInt(SETTING_ROW2_CONTENT, LINE_SATSPERUNIT);
|
||||||
|
}
|
||||||
|
if (!preferences.isKey(SETTING_ROW3_CONTENT))
|
||||||
|
{
|
||||||
|
preferences.putUInt(SETTING_ROW3_CONTENT, LINE_MEMPOOL_FEES);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!preferences.isKey(SETTING_CURRENCY))
|
||||||
|
{
|
||||||
|
preferences.putString(SETTING_CURRENCY, CURRENCY_USD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupWifi()
|
void setupWifi()
|
||||||
|
|
18
src/data.cpp
18
src/data.cpp
|
@ -6,6 +6,9 @@ const String mempoolPriceApiUrl = mempoolInstance + "/api/v1/prices";
|
||||||
const String mempoolBlockApiUrl = mempoolInstance + "/api/blocks/tip/height";
|
const String mempoolBlockApiUrl = mempoolInstance + "/api/blocks/tip/height";
|
||||||
const String mempoolFeeApiUrl = mempoolInstance + "/api/v1/fees/recommended";
|
const String mempoolFeeApiUrl = mempoolInstance + "/api/v1/fees/recommended";
|
||||||
|
|
||||||
|
uint lastPrice;
|
||||||
|
uint lastBlock;
|
||||||
|
|
||||||
uint getPrice()
|
uint getPrice()
|
||||||
{
|
{
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
|
@ -22,10 +25,10 @@ uint getPrice()
|
||||||
String payload = http.getString();
|
String payload = http.getString();
|
||||||
JsonDocument doc;
|
JsonDocument doc;
|
||||||
deserializeJson(doc, payload);
|
deserializeJson(doc, payload);
|
||||||
usdPrice = doc["USD"].as<uint>();
|
|
||||||
eurPrice = doc["EUR"].as<uint>();
|
|
||||||
|
|
||||||
return usdPrice;
|
lastPrice = doc[preferences.getString(SETTING_CURRENCY)].as<uint>();
|
||||||
|
|
||||||
|
return lastPrice;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,7 +39,7 @@ uint getPrice()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getBlock()
|
uint getBlock()
|
||||||
{
|
{
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
|
|
||||||
|
@ -49,9 +52,10 @@ String getBlock()
|
||||||
uint usdPrice, eurPrice;
|
uint usdPrice, eurPrice;
|
||||||
if (httpCode == 200)
|
if (httpCode == 200)
|
||||||
{
|
{
|
||||||
String payload = http.getString();
|
uint payload = http.getString().toInt();
|
||||||
|
|
||||||
return payload;
|
lastBlock = payload;
|
||||||
|
return lastBlock;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -59,7 +63,7 @@ String getBlock()
|
||||||
}
|
}
|
||||||
http.end();
|
http.end();
|
||||||
|
|
||||||
return "";
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getMempoolFees()
|
String getMempoolFees()
|
||||||
|
|
|
@ -8,5 +8,5 @@
|
||||||
#include "shared.hpp"
|
#include "shared.hpp"
|
||||||
|
|
||||||
uint getPrice();
|
uint getPrice();
|
||||||
String getBlock();
|
uint getBlock();
|
||||||
String getMempoolFees();
|
String getMempoolFees();
|
|
@ -89,7 +89,7 @@ void loop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String block = getBlock();
|
String block = String(getBlock());
|
||||||
|
|
||||||
uint tryCount = 0;
|
uint tryCount = 0;
|
||||||
while (block.equals(""))
|
while (block.equals(""))
|
||||||
|
|
|
@ -56,13 +56,28 @@
|
||||||
#define ICON_CHECK "Q"
|
#define ICON_CHECK "Q"
|
||||||
#define ICON_WARNING "R"
|
#define ICON_WARNING "R"
|
||||||
|
|
||||||
|
#define SETTING_ROW1_CONTENT "row1"
|
||||||
|
#define SETTING_ROW2_CONTENT "row2"
|
||||||
|
#define SETTING_ROW3_CONTENT "row3"
|
||||||
|
#define SETTING_CURRENCY "currency"
|
||||||
|
|
||||||
const int LINE_BLOCKHEIGHT = 0;
|
const int LINE_BLOCKHEIGHT = 0;
|
||||||
const int LINE_HALVING_COUNTDOWN = 1;
|
const int LINE_MEMPOOL_FEES = 1;
|
||||||
const int LINE_SATSPERDOLLAR = 2;
|
const int LINE_MEMPOOL_FEES_MEDIAN = 2;
|
||||||
const int LINE_FIATPRICE = 3;
|
const int LINE_HALVING_COUNTDOWN = 10;
|
||||||
const int LINE_MEMPOOL_FEES = 4;
|
const int LINE_SATSPERUNIT = 20;
|
||||||
const int LINE_TIME = 5;
|
const int LINE_FIATPRICE = 30;
|
||||||
const int LINE_DATE = 6;
|
const int LINE_MARKETCAP = 40;
|
||||||
|
const int LINE_TIME = 99;
|
||||||
|
const int LINE_DATE = 100;
|
||||||
|
|
||||||
|
#define CURRENCY_USD "USD"
|
||||||
|
#define CURRENCY_EUR "EUR"
|
||||||
|
#define CURRENCY_GBP "GBP"
|
||||||
|
#define CURRENCY_CAD "CAD"
|
||||||
|
#define CURRENCY_CHF "CHF"
|
||||||
|
#define CURRENCY_AUD "AUD"
|
||||||
|
#define CURRENCY_JPY "JPY"
|
||||||
|
|
||||||
extern WiFiClientSecure client;
|
extern WiFiClientSecure client;
|
||||||
extern GxEPD2_BW<EPD_CLASS, EPD_CLASS::HEIGHT> display;
|
extern GxEPD2_BW<EPD_CLASS, EPD_CLASS::HEIGHT> display;
|
||||||
|
|
|
@ -2,12 +2,20 @@
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
|
||||||
AsyncWebServer server(80);
|
AsyncWebServer server(80);
|
||||||
|
String uintSettings[] = {SETTING_ROW1_CONTENT, SETTING_ROW2_CONTENT, SETTING_ROW3_CONTENT};
|
||||||
|
|
||||||
void setupWebserver() {
|
void setupWebserver()
|
||||||
if (!LittleFS.begin(true)) {
|
{
|
||||||
|
if (!LittleFS.begin(true))
|
||||||
|
{
|
||||||
Serial.println(F("An Error has occurred while mounting LittleFS"));
|
Serial.println(F("An Error has occurred while mounting LittleFS"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server.on("/api/settings", HTTP_GET, onApiSettingsGet);
|
||||||
|
AsyncCallbackJsonWebHandler *settingsPatchHandler =
|
||||||
|
new AsyncCallbackJsonWebHandler("/api/json/settings", onApiSettingsPatch);
|
||||||
|
server.addHandler(settingsPatchHandler);
|
||||||
|
|
||||||
server.serveStatic("/build", LittleFS, "/build");
|
server.serveStatic("/build", LittleFS, "/build");
|
||||||
|
|
||||||
server.on("/", HTTP_GET, onIndex);
|
server.on("/", HTTP_GET, onIndex);
|
||||||
|
@ -20,17 +28,54 @@ void setupWebserver() {
|
||||||
server.begin();
|
server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onIndex(AsyncWebServerRequest *request) {
|
void onApiSettingsGet(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
JsonDocument root;
|
||||||
|
for (String setting : uintSettings)
|
||||||
|
{
|
||||||
|
root[setting] = preferences.getUInt(setting.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
AsyncResponseStream *response =
|
||||||
|
request->beginResponseStream("application/json");
|
||||||
|
serializeJson(root, *response);
|
||||||
|
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
|
||||||
|
{
|
||||||
|
JsonObject settings = json.as<JsonObject>();
|
||||||
|
|
||||||
|
for (String setting : uintSettings)
|
||||||
|
{
|
||||||
|
if (settings.containsKey(setting))
|
||||||
|
{
|
||||||
|
preferences.putUInt(setting.c_str(), settings[setting].as<uint>());
|
||||||
|
Serial.printf("Setting %s to %d\r\n", setting.c_str(),
|
||||||
|
settings[setting].as<uint>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onIndex(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
request->send(LittleFS, "/index.html", String(), false);
|
request->send(LittleFS, "/index.html", String(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onNotFound(AsyncWebServerRequest *request) {
|
void onNotFound(AsyncWebServerRequest *request)
|
||||||
if (request->method() == HTTP_OPTIONS ||
|
{
|
||||||
request->hasHeader("Sec-Fetch-Mode")) {
|
if (request->method() == HTTP_OPTIONS ||
|
||||||
|
request->hasHeader("Sec-Fetch-Mode"))
|
||||||
|
{
|
||||||
// Serial.printf("NotFound, Return[%d]\n", 200);
|
// Serial.printf("NotFound, Return[%d]\n", 200);
|
||||||
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Serial.printf("NotFound, Return[%d]\n", 404);
|
// Serial.printf("NotFound, Return[%d]\n", 404);
|
||||||
request->send(404);
|
request->send(404);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,15 @@
|
||||||
|
|
||||||
// Keep order of includes because of conflicts
|
// Keep order of includes because of conflicts
|
||||||
#include "ESPAsyncWebServer.h"
|
#include "ESPAsyncWebServer.h"
|
||||||
|
#include "AsyncJson.h"
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
#include <shared.hpp>
|
||||||
|
|
||||||
void setupWebserver();
|
void setupWebserver();
|
||||||
|
|
||||||
|
void onApiSettingsGet(AsyncWebServerRequest *request);
|
||||||
|
void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json);
|
||||||
|
|
||||||
void onIndex(AsyncWebServerRequest *request);
|
void onIndex(AsyncWebServerRequest *request);
|
||||||
void onNotFound(AsyncWebServerRequest *request);
|
void onNotFound(AsyncWebServerRequest *request);
|
Loading…
Reference in a new issue