More efficient handling of multiple fonts, restore data bugfix
All checks were successful
BTClock CI / build (push) Successful in 12m16s
BTClock CI / merge (map[name:btclock_rev_b version:esp32s3], 213epd) (push) Successful in 31s
BTClock CI / merge (map[name:btclock_v8 version:esp32s3], 213epd) (push) Successful in 21s
BTClock CI / merge (map[name:lolin_s3_mini version:esp32s3], 213epd) (push) Successful in 29s
BTClock CI / merge (map[name:lolin_s3_mini version:esp32s3], 29epd) (push) Successful in 19s
BTClock CI / release (push) Successful in 39s

This commit is contained in:
Djuri 2024-12-30 00:53:50 +01:00
parent 90d91ba216
commit 13c8e67b4c
9 changed files with 96 additions and 94 deletions

2
data

@ -1 +1 @@
Subproject commit 48e585d4ec12bbc441499936d7cbf53d4307b9ec
Subproject commit 0041ec3d9a174955383836bba02caf79f3961072

View file

@ -15,9 +15,35 @@ struct FontData {
const uint8_t yAdvance;
};
// Font name constants
namespace FontNames {
static const String ANTONIO = "antonio";
static const String OSWALD = "oswald";
static const std::array<String, 2> AVAILABLE_FONTS = {
ANTONIO,
OSWALD
};
static const std::array<String, 2>& getAvailableFonts() {
return AVAILABLE_FONTS;
}
}
class FontLoader {
public:
static GFXfont* loadCompressedFont(const FontData& fontData) {
return loadCompressedFont(
fontData.compressedData,
fontData.glyphs,
fontData.compressedSize,
fontData.originalSize,
fontData.first,
fontData.last,
fontData.yAdvance
);
}
static GFXfont* loadCompressedFont(
const uint8_t* compressedData,
const GFXglyph* glyphs,

View file

@ -161,73 +161,21 @@ void forceFullRefresh()
GFXfont font90;
void setupDisplays()
{
String fontName = preferences.getString("fontName", DEFAULT_FONT_NAME); // Default to antonio
if (fontName == "antonio")
{
void loadFonts(const String& fontName) {
if (fontName == FontNames::ANTONIO) {
// Load Antonio fonts
antonioFonts.big = FontLoader::loadCompressedFont(
Antonio_SemiBold90pt7b_Properties.compressedData,
Antonio_SemiBold90pt7b_Properties.glyphs,
Antonio_SemiBold90pt7b_Properties.compressedSize,
Antonio_SemiBold90pt7b_Properties.originalSize,
Antonio_SemiBold90pt7b_Properties.first,
Antonio_SemiBold90pt7b_Properties.last,
Antonio_SemiBold90pt7b_Properties.yAdvance);
antonioFonts.medium = FontLoader::loadCompressedFont(
Antonio_SemiBold40pt7b_Properties.compressedData,
Antonio_SemiBold40pt7b_Properties.glyphs,
Antonio_SemiBold40pt7b_Properties.compressedSize,
Antonio_SemiBold40pt7b_Properties.originalSize,
Antonio_SemiBold40pt7b_Properties.first,
Antonio_SemiBold40pt7b_Properties.last,
Antonio_SemiBold40pt7b_Properties.yAdvance);
antonioFonts.small = FontLoader::loadCompressedFont(
Antonio_SemiBold20pt7b_Properties.compressedData,
Antonio_SemiBold20pt7b_Properties.glyphs,
Antonio_SemiBold20pt7b_Properties.compressedSize,
Antonio_SemiBold20pt7b_Properties.originalSize,
Antonio_SemiBold20pt7b_Properties.first,
Antonio_SemiBold20pt7b_Properties.last,
Antonio_SemiBold20pt7b_Properties.yAdvance);
antonioFonts.big = FontLoader::loadCompressedFont(Antonio_SemiBold90pt7b_Properties);
antonioFonts.medium = FontLoader::loadCompressedFont(Antonio_SemiBold40pt7b_Properties);
antonioFonts.small = FontLoader::loadCompressedFont(Antonio_SemiBold20pt7b_Properties);
FONT_BIG = antonioFonts.big;
FONT_MEDIUM = antonioFonts.medium;
FONT_SMALL = antonioFonts.small;
}
else if (fontName == "oswald")
{
} else if (fontName == FontNames::OSWALD) {
// Load Oswald fonts
oswaldFonts.big = FontLoader::loadCompressedFont(
Oswald_Medium80pt7b_Properties.compressedData,
Oswald_Medium80pt7b_Properties.glyphs,
Oswald_Medium80pt7b_Properties.compressedSize,
Oswald_Medium80pt7b_Properties.originalSize,
Oswald_Medium80pt7b_Properties.first,
Oswald_Medium80pt7b_Properties.last,
Oswald_Medium80pt7b_Properties.yAdvance);
oswaldFonts.medium = FontLoader::loadCompressedFont(
Oswald_Medium30pt7b_Properties.compressedData,
Oswald_Medium30pt7b_Properties.glyphs,
Oswald_Medium30pt7b_Properties.compressedSize,
Oswald_Medium30pt7b_Properties.originalSize,
Oswald_Medium30pt7b_Properties.first,
Oswald_Medium30pt7b_Properties.last,
Oswald_Medium30pt7b_Properties.yAdvance);
oswaldFonts.small = FontLoader::loadCompressedFont(
Oswald_Medium20pt7b_Properties.compressedData,
Oswald_Medium20pt7b_Properties.glyphs,
Oswald_Medium20pt7b_Properties.compressedSize,
Oswald_Medium20pt7b_Properties.originalSize,
Oswald_Medium20pt7b_Properties.first,
Oswald_Medium20pt7b_Properties.last,
Oswald_Medium20pt7b_Properties.yAdvance);
oswaldFonts.big = FontLoader::loadCompressedFont(Oswald_Medium80pt7b_Properties);
oswaldFonts.medium = FontLoader::loadCompressedFont(Oswald_Medium30pt7b_Properties);
oswaldFonts.small = FontLoader::loadCompressedFont(Oswald_Medium20pt7b_Properties);
FONT_BIG = oswaldFonts.big;
FONT_MEDIUM = oswaldFonts.medium;
@ -235,53 +183,49 @@ void setupDisplays()
}
FONT_SATSYMBOL = &Satoshi_Symbol90pt7b;
}
void setupDisplays() {
// Load fonts based on preference
String fontName = preferences.getString("fontName", DEFAULT_FONT_NAME);
loadFonts(fontName);
// Initialize displays
std::lock_guard<std::mutex> lockMcp(mcpMutex);
for (uint i = 0; i < NUM_SCREENS; i++)
{
for (uint i = 0; i < NUM_SCREENS; i++) {
displays[i].init(0, true, 30);
}
// Create update queue and task
updateQueue = xQueueCreate(UPDATE_QUEUE_SIZE, sizeof(UpdateDisplayTaskItem));
xTaskCreate(prepareDisplayUpdateTask, "PrepareUpd", EPD_TASK_STACK_SIZE * 2, NULL, 11, NULL);
for (uint i = 0; i < NUM_SCREENS; i++)
{
// Create display update tasks
for (uint i = 0; i < NUM_SCREENS; i++) {
int *taskParam = new int;
*taskParam = i;
xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), EPD_TASK_STACK_SIZE, taskParam,
11, &tasks[i]); // create task
xTaskCreate(updateDisplay, ("EpdUpd" + String(i)).c_str(), EPD_TASK_STACK_SIZE, taskParam, 11, &tasks[i]);
}
// Hold lower button to enable "storage mode" (prevents burn-in of ePaper displays)
if (mcp1.read1(0) == LOW)
{
// Check for storage mode (prevents burn-in)
if (mcp1.read1(0) == LOW) {
setFgColor(GxEPD_BLACK);
setBgColor(GxEPD_WHITE);
epdContent.fill("");
}
else
{
// Get custom text from preferences or use default "BTCLOCK"
} else {
// Initialize with custom text or default
String customText = preferences.getString("displayText", DEFAULT_BOOT_TEXT);
// Initialize array with spaces
std::array<String, NUM_SCREENS> newContent;
newContent.fill(" ");
// Fill in the custom text, truncating if longer than NUM_SCREENS
for (size_t i = 0; i < std::min(customText.length(), (size_t)NUM_SCREENS); i++) {
newContent[i] = String(customText[i]);
newContent[i] = String(customText[i]);
}
epdContent = newContent;
}
setEpdContent(epdContent);
setEpdContent(epdContent);
}
void setEpdContent(std::array<String, NUM_SCREENS> newEpdContent)
@ -527,8 +471,8 @@ void showDigit(const uint dispNum, char chr, bool partial, const GFXfont *font)
if (chr == '.')
{
displays[dispNum].fillRect(x, y, displays[dispNum].width(),
round(displays[dispNum].height() * 0.9), getBgColor());
displays[dispNum].fillRect(0, 0, displays[dispNum].width(),
round(displays[dispNum].height() * 0.67), getBgColor());
}
}

View file

@ -31,7 +31,6 @@
#ifdef USE_QR
#include "qrcodegen.h"
#endif
// extern TaskHandle_t epdTaskHandle;
typedef struct {
char dispNum;
@ -39,6 +38,7 @@ typedef struct {
void forceFullRefresh();
void setupDisplays();
void loadFonts(const String& fontName);
void splitText(const uint dispNum, const String &top, const String &bottom,
bool partial);

View file

@ -110,15 +110,17 @@ void processNewPrice(uint newPrice, char currency)
if (lastUpdateMap.find(currency) == lastUpdateMap.end() ||
(currentTime - lastUpdateMap[currency]) > minSecPriceUpd)
{
// const unsigned long oldPrice = currentPrice;
currencyMap[currency] = newPrice;
if (currency == CURRENCY_USD && ( lastUpdateMap[currency] == 0 ||
(currentTime - lastUpdateMap[currency]) > 120))
// Store price in preferences if enough time has passed
if (lastUpdateMap[currency] == 0 || (currentTime - lastUpdateMap[currency]) > 120)
{
preferences.putUInt("lastPrice", currentPrice);
String prefKey = String("lastPrice_") + getCurrencyCode(currency).c_str();
preferences.putUInt(prefKey.c_str(), newPrice);
}
lastUpdateMap[currency] = currentTime;
// if (abs((int)(oldPrice-currentPrice)) > round(0.0015*oldPrice)) {
if (workQueue != nullptr && (ScreenHandler::getCurrentScreen() == SCREEN_BTC_TICKER ||
ScreenHandler::getCurrentScreen() == SCREEN_SATS_PER_CURRENCY ||
ScreenHandler::getCurrentScreen() == SCREEN_MARKET_CAP))
@ -126,7 +128,24 @@ void processNewPrice(uint newPrice, char currency)
WorkItem priceUpdate = {TASK_PRICE_UPDATE, currency};
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
}
//}
}
}
void loadStoredPrices()
{
// Load prices for all supported currencies
std::vector<std::string> currencies = getAvailableCurrencies();
for (const std::string &currency : currencies) {
// Get first character as the currency identifier
String prefKey = String("lastPrice_") + currency.c_str();
uint storedPrice = preferences.getUInt(prefKey.c_str(), 0);
if (storedPrice > 0) {
currencyMap[getCurrencyChar(currency)] = storedPrice;
// Initialize lastUpdateMap to 0 so next update will store immediately
lastUpdateMap[getCurrencyChar(currency)] = 0;
}
}
}

View file

@ -27,4 +27,5 @@ void stopPriceNotify();
void restartPriceNotify();
bool getPriceNotifyInit();
uint getLastPriceUpdate(char currency);
uint getLastPriceUpdate(char currency);
void loadStoredPrices();

View file

@ -321,6 +321,7 @@ void taskScreenRotate(void *pvParameters) {
void setupTasks() {
workQueue = xQueueCreate(WORK_QUEUE_SIZE, sizeof(WorkItem));
loadStoredPrices();
xTaskCreate(workerTask, "workerTask", 4096, NULL, tskIDLE_PRIORITY,
&workerTaskHandle);

View file

@ -97,6 +97,16 @@ namespace ArduinoJson {
array.add(item);
}
};
template <size_t N>
struct Converter<std::array<String, N>> {
static void toJson(const std::array<String, N>& src, JsonVariant dst) {
JsonArray array = dst.to<JsonArray>();
for (const String& item : src) {
array.add(item);
}
}
};
}
class HttpHelper {

View file

@ -676,6 +676,7 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
root["nostrZapPubkey"] = preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY);
root["ledFlashOnZap"] = preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP);
root["fontName"] = preferences.getString("fontName", DEFAULT_FONT_NAME);
root["availableFonts"] = FontNames::getAvailableFonts();
// Custom endpoint settings (only used for CUSTOM_SOURCE)
root["customEndpoint"] = preferences.getString("customEndpoint", DEFAULT_CUSTOM_ENDPOINT);
root["customEndpointDisableSSL"] = preferences.getBool("customEndpointDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL);