diff --git a/data/src/index.html b/data/src/index.html index a0b4466..a601d7e 100644 --- a/data/src/index.html +++ b/data/src/index.html @@ -63,8 +63,8 @@
{{ memUsage }}%
-
Memory usage
-
{{ memFree }} / {{ memTotal }} kB
+
Memory free
+
{{ memFree }} / {{ memTotal }} KiB

diff --git a/data/src/js/script.ts b/data/src/js/script.ts index e370e02..1125f9b 100644 --- a/data/src/js/script.ts +++ b/data/src/js/script.ts @@ -1,6 +1,6 @@ import './helpers.js'; -var screens = ["Block Height", "Moscow Time", "Ticker", "Time", "Halving countdown"]; +var screens = ["Block Height", "Moscow Time", "Ticker", "Time", "Halving countdown", "Market Cap"]; toTime = (secs) => { var hours = Math.floor(secs / (60 * 60)); @@ -28,7 +28,7 @@ getBcStatus = () => { var source = document.getElementById("entry-template").innerHTML; var template = Handlebars.compile(source); - var context = { timerRunning: jsonData.timerRunning, memUsage: Math.round(jsonData.espFreeHeap / jsonData.espHeapSize * 100), memFree: (jsonData.espFreeHeap / 1000), memTotal: (jsonData.espHeapSize / 1000), uptime: toTime(jsonData.espUptime), currentScreen: jsonData.currentScreen, rendered: jsonData.rendered, data: jsonData.data, screens: screens, ledStatus: jsonData.ledStatus ? jsonData.ledStatus.map((t) => (t).toString(16)) : [] }; + var context = { timerRunning: jsonData.timerRunning, memUsage: Math.round(jsonData.espFreeHeap / jsonData.espHeapSize * 100), memFree: (jsonData.espFreeHeap / 1024), memTotal: (jsonData.espHeapSize / 1024), uptime: toTime(jsonData.espUptime), currentScreen: jsonData.currentScreen, rendered: jsonData.rendered, data: jsonData.data, screens: screens, ledStatus: jsonData.ledStatus ? jsonData.ledStatus.map((t) => (t).toString(16)) : [] }; document.getElementById('output').innerHTML = template(context); diff --git a/src/lib/epd.cpp b/src/lib/epd.cpp index 3cc5499..b936e00 100644 --- a/src/lib/epd.cpp +++ b/src/lib/epd.cpp @@ -26,7 +26,7 @@ void setFgColor(int color) void showSetupQr(const String &ssid, const String &password) { - char displayIndex = 6; + uint displayIndex = 6; const String text = "WIFI:S:" + ssid + ";T:WPA;P:" + password + ";;"; diff --git a/src/lib/functions.cpp b/src/lib/functions.cpp index 29d6642..0e6cd4e 100644 --- a/src/lib/functions.cpp +++ b/src/lib/functions.cpp @@ -180,7 +180,9 @@ void setupPreferences() {SCREEN_MSCW_TIME, "Sats per dollar"}, {SCREEN_BTC_TICKER, "Ticker"}, {SCREEN_TIME, "Time"}, - {SCREEN_HALVING_COUNTDOWN, "Halving countdown"}}; + {SCREEN_HALVING_COUNTDOWN, "Halving countdown"}, + {SCREEN_MARKET_CAP, "Market Cap"} + }; #ifdef WITH_RGB_LED pixels.setBrightness(preferences.getUInt("ledBrightness", 128)); @@ -225,23 +227,21 @@ void handleScreenTasks(uint screen) switch (currentScreen) { case SCREEN_BLOCK_HEIGHT: - if (blockNotifyTaskHandle) - { - vTaskResume(blockNotifyTaskHandle); - } - break; case SCREEN_HALVING_COUNTDOWN: if (blockNotifyTaskHandle) vTaskResume(blockNotifyTaskHandle); break; case SCREEN_BTC_TICKER: - if (getPriceTaskHandle) - vTaskResume(getPriceTaskHandle); - break; case SCREEN_MSCW_TIME: if (getPriceTaskHandle) vTaskResume(getPriceTaskHandle); break; + case SCREEN_MARKET_CAP: + if (getPriceTaskHandle) + vTaskResume(getPriceTaskHandle); + if (blockNotifyTaskHandle) + vTaskResume(blockNotifyTaskHandle); + break; case SCREEN_TIME: if (minuteTaskHandle) { @@ -388,7 +388,7 @@ void showNetworkSettings() } epdContent[NUM_SCREENS-2] = "RAM/Status"; - epdContent[NUM_SCREENS-1] = String((int)round(ESP.getFreeHeap()/1000)) + "/" + (int)round(ESP.getHeapSize()/1000); + epdContent[NUM_SCREENS-1] = String((int)round(ESP.getFreeHeap()/1024)) + "/" + (int)round(ESP.getHeapSize()/1024); CustomTextScreen::setText(epdContent); diff --git a/src/lib/utils.cpp b/src/lib/utils.cpp new file mode 100644 index 0000000..245d4b5 --- /dev/null +++ b/src/lib/utils.cpp @@ -0,0 +1,43 @@ +#include "utils.hpp"; + +double getSupplyAtBlock(uint blockNr) { + if (blockNr >= 33 * 210000) { + return 20999999.9769; + } + + const int initialBlockReward = 50; // Initial block reward + const int halvingInterval = 210000; // Number of blocks before halving + + int halvingCount = blockNr / halvingInterval; + double totalBitcoinInCirculation = 0; + + for (int i = 0; i < halvingCount; ++i) { + totalBitcoinInCirculation += halvingInterval * initialBlockReward * std::pow(0.5, i); + } + + totalBitcoinInCirculation += (blockNr % halvingInterval) * initialBlockReward * std::pow(0.5, halvingCount); + + return totalBitcoinInCirculation; +} + +std::string formatNumberWithSuffix(int64_t num) { + const long long quadrillion = 1000000000000000LL; + const long long trillion = 1000000000000LL; + const long long billion = 1000000000; + const long long million = 1000000; + const long long thousand = 1000; + + if (num >= quadrillion) { + return std::to_string(num / quadrillion) + "Q"; + } else if (num >= trillion) { + return std::to_string(num / trillion) + "T"; + } else if (num >= billion) { + return std::to_string(num / billion) + "B"; + } else if (num >= million) { + return std::to_string(num / million) + "M"; + } else if (num >= thousand) { + return std::to_string(num / thousand) + "K"; + } else { + return std::to_string(num); + } +} diff --git a/src/lib/utils.hpp b/src/lib/utils.hpp new file mode 100644 index 0000000..c0ffac7 --- /dev/null +++ b/src/lib/utils.hpp @@ -0,0 +1,6 @@ +#pragma once + +#include "shared.hpp" + +double getSupplyAtBlock(uint blockNr); +std::string formatNumberWithSuffix(int64_t num); \ No newline at end of file diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index a9a9d1a..4a3b4f2 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -67,7 +67,7 @@ void setupWebserver() /** * @Api * @Path("/api/status") -*/ + */ void onApiStatus(AsyncWebServerRequest *request) { AsyncResponseStream *response = request->beginResponseStream("application/json"); @@ -110,7 +110,7 @@ void onApiStatus(AsyncWebServerRequest *request) /** * @Api * @Path("/api/action/pause") -*/ + */ void onApiActionPause(AsyncWebServerRequest *request) { timerRunning = false; @@ -122,7 +122,7 @@ void onApiActionPause(AsyncWebServerRequest *request) /** * @Api * @Path("/api/action/full_refresh") -*/ + */ void onApiFullRefresh(AsyncWebServerRequest *request) { @@ -134,7 +134,7 @@ void onApiFullRefresh(AsyncWebServerRequest *request) /** * @Api * @Path("/api/action/timer_restart") -*/ + */ void onApiActionTimerRestart(AsyncWebServerRequest *request) { // moment = millis(); @@ -148,7 +148,7 @@ void onApiActionTimerRestart(AsyncWebServerRequest *request) * @Api * @Path("/api/action/update") * @Parameter int rate Time in minutes -*/ + */ void onApiActionUpdate(AsyncWebServerRequest *request) { if (request->hasParam("rate")) @@ -167,10 +167,10 @@ void onApiActionUpdate(AsyncWebServerRequest *request) * @Api * @Method GET * @Path("/api/settings") -*/ + */ void onApiSettingsGet(AsyncWebServerRequest *request) { - StaticJsonDocument<768> root; + StaticJsonDocument<1536> root; root["numScreens"] = NUM_SCREENS; root["fgColor"] = getFgColor(); root["bgColor"] = getBgColor(); @@ -212,7 +212,7 @@ void onApiSettingsGet(AsyncWebServerRequest *request) AsyncResponseStream *response = request->beginResponseStream("application/json"); serializeJson(root, *response); - + request->send(response); } diff --git a/src/main.cpp b/src/main.cpp index a21cf8b..5d30115 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,7 @@ #include "screens/ticker.hpp" #include "screens/time.hpp" #include "screens/halvingcountdown.hpp" +#include "screens/market_cap.hpp" #include "tasks/ha.hpp" #include "tasks/epd.hpp" @@ -62,6 +63,7 @@ void setup() BlockHeightScreen::init(); HalvingCountdownScreen::init(); TickerScreen::init(); + MarketCapScreen::init(); #ifdef WITH_BUTTONS setupButtonTask(); diff --git a/src/screens/blockheight.cpp b/src/screens/blockheight.cpp index 62d8615..44bfec4 100644 --- a/src/screens/blockheight.cpp +++ b/src/screens/blockheight.cpp @@ -57,4 +57,8 @@ std::array BlockHeightScreen::getEpdContent() // std::copy(std::begin(BlockHeightScreen::epdContent), std::end(BlockHeightScreen::epdContent), std::begin(ret)); return ret; +} + +uint BlockHeightScreen::getBlockNr() { + return blockNr; } \ No newline at end of file diff --git a/src/screens/blockheight.hpp b/src/screens/blockheight.hpp index e44443b..c0a4440 100644 --- a/src/screens/blockheight.hpp +++ b/src/screens/blockheight.hpp @@ -17,4 +17,5 @@ public: static void showScreen(); static void onNewBlock(uint blockNr); static std::array getEpdContent(); + static uint getBlockNr(); }; \ No newline at end of file diff --git a/src/screens/market_cap.cpp b/src/screens/market_cap.cpp new file mode 100644 index 0000000..46db538 --- /dev/null +++ b/src/screens/market_cap.cpp @@ -0,0 +1,30 @@ +#include "market_cap.hpp" + +uint MarketCapScreen::satsPerDollar = 0; +std::array MarketCapScreen::epdContent = {"", "", "", "", "", "", ""}; + +void MarketCapScreen::init() +{ + // Dependent on price and blocks + MarketCapScreen::showScreen(); +} + +void MarketCapScreen::showScreen() +{ + double supply = getSupplyAtBlock(BlockHeightScreen::getBlockNr()); + int64_t marketCap = static_cast(supply * double(TickerScreen::getPrice())); + + std::string priceString = "$" + formatNumberWithSuffix(marketCap); + priceString.insert(priceString.begin(), NUM_SCREENS - priceString.length(), ' '); + + epdContent[0] = "USD/MCAP"; + for (uint i = 1; i < NUM_SCREENS; i++) + { + MarketCapScreen::epdContent[i] = priceString[i]; + } +} + +std::array MarketCapScreen::getEpdContent() +{ + return MarketCapScreen::epdContent; +} \ No newline at end of file diff --git a/src/screens/market_cap.hpp b/src/screens/market_cap.hpp new file mode 100644 index 0000000..e7e0e79 --- /dev/null +++ b/src/screens/market_cap.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "base.hpp" +#include "config.h" +#include "shared.hpp" +#include "lib/utils.hpp" +#include "blockheight.hpp"; +#include "ticker.hpp"; +#include "tasks/epd.hpp" + +class MarketCapScreen { + protected: + static uint satsPerDollar; + static std::array epdContent; + public: + static void init(); + static void showScreen(); + static void onPriceUpdate(uint price); + static std::array getEpdContent(); +}; \ No newline at end of file diff --git a/src/screens/sats_per_dollar.cpp b/src/screens/sats_per_dollar.cpp deleted file mode 100644 index b292b94..0000000 --- a/src/screens/sats_per_dollar.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// #include "sats_per_dollar.hpp" - -// uint SatsPerDollarScreen::satsPerDollar = 0; -// std::array SatsPerDollarScreen::epdContent = { "", "", "", "", "", "", "" }; - -// void SatsPerDollarScreen::init() { -// SatsPerDollarScreen::satsPerDollar = int(round(1 / preferences.getFloat("btcPrice", 12345) * 10e7)); -// setupGetPriceTask(); -// SatsPerDollarScreen::showScreen(); -// } - -// void SatsPerDollarScreen::showScreen() { -// std::string satsPerDollarString = String(SatsPerDollarScreen::satsPerDollar).c_str(); -// satsPerDollarString.insert(satsPerDollarString.begin(), 7 - satsPerDollarString.length(), ' '); -// epdContent[0] = "MSCW/TIME"; -// for (uint i = 1; i < NUM_SCREENS; i++) -// { -// SatsPerDollarScreen::epdContent[i] = satsPerDollarString[i]; -// } -// } - -// void SatsPerDollarScreen::onPriceUpdate(uint price) { -// SatsPerDollarScreen::satsPerDollar = int(round(1 / float(price) * 10e7)); - -// SatsPerDollarScreen::showScreen(); -// } - -// std::array SatsPerDollarScreen::getEpdContent() { -// return SatsPerDollarScreen::epdContent; -// } \ No newline at end of file diff --git a/src/screens/sats_per_dollar.hpp b/src/screens/sats_per_dollar.hpp deleted file mode 100644 index 428b49c..0000000 --- a/src/screens/sats_per_dollar.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// #pragma once - -// #include "base.hpp" -// #include "config.h" -// #include "shared.hpp" -// #include "tasks/epd.hpp" - -// class SatsPerDollarScreen { -// protected: -// static uint satsPerDollar; -// static std::array epdContent; -// public: -// static void init(); -// static void showScreen(); -// static void onPriceUpdate(uint price); -// static std::array getEpdContent(); -// }; \ No newline at end of file diff --git a/src/screens/ticker.cpp b/src/screens/ticker.cpp index da2f7f0..b902477 100644 --- a/src/screens/ticker.cpp +++ b/src/screens/ticker.cpp @@ -48,4 +48,8 @@ std::array TickerScreen::getEpdContentSats() { return epdContentSats; +} + +uint TickerScreen::getPrice() { + return price; } \ No newline at end of file diff --git a/src/screens/ticker.hpp b/src/screens/ticker.hpp index 420e6ed..df9adf8 100644 --- a/src/screens/ticker.hpp +++ b/src/screens/ticker.hpp @@ -18,4 +18,5 @@ public: static void onPriceUpdate(uint price); static std::array getEpdContent(); static std::array getEpdContentSats(); + static uint getPrice(); }; \ No newline at end of file diff --git a/src/shared.hpp b/src/shared.hpp index e3af487..42d038f 100644 --- a/src/shared.hpp +++ b/src/shared.hpp @@ -55,9 +55,11 @@ const PROGMEM int SCREEN_MSCW_TIME = 1; const PROGMEM int SCREEN_BTC_TICKER = 2; const PROGMEM int SCREEN_TIME = 3; const PROGMEM int SCREEN_HALVING_COUNTDOWN = 4; +const PROGMEM int SCREEN_MARKET_CAP = 5; + const PROGMEM int SCREEN_COUNTDOWN = 98; const PROGMEM int SCREEN_CUSTOM = 99; -const PROGMEM int screens[5] = { SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_BTC_TICKER, SCREEN_TIME, SCREEN_HALVING_COUNTDOWN }; +const PROGMEM int screens[6] = { SCREEN_BLOCK_HEIGHT, SCREEN_MSCW_TIME, SCREEN_BTC_TICKER, SCREEN_TIME, SCREEN_HALVING_COUNTDOWN, SCREEN_MARKET_CAP }; const uint screenCount = sizeof(screens) / sizeof(int); diff --git a/src/tasks/epd.cpp b/src/tasks/epd.cpp index 10fa326..a20739b 100644 --- a/src/tasks/epd.cpp +++ b/src/tasks/epd.cpp @@ -192,6 +192,9 @@ void taskEpd(void *pvParameters) case SCREEN_HALVING_COUNTDOWN: epdContent = HalvingCountdownScreen::getEpdContent(); break; + case SCREEN_MARKET_CAP: + epdContent = MarketCapScreen::getEpdContent(); + break; case SCREEN_COUNTDOWN: epdContent = CountdownScreen::getEpdContent(); break; @@ -325,7 +328,7 @@ extern "C" void updateDisplay(void *pvParameters) noexcept if (epdContent[epdIndex].compareTo(currentEpdContent[epdIndex]) != 0) { - displays[epdIndex].init(0, false, 20); // Little longer reset duration because of MCP + displays[epdIndex].init(0, false); // Little longer reset duration because of MCP #ifndef USE_UNIVERSAL_PIN resetSingleDisplay(epdIndex); #endif diff --git a/src/tasks/epd.hpp b/src/tasks/epd.hpp index 7378c0e..f1a7644 100644 --- a/src/tasks/epd.hpp +++ b/src/tasks/epd.hpp @@ -11,10 +11,12 @@ #include "screens/blockheight.hpp" #include "screens/ticker.hpp" #include "screens/time.hpp" -#include "screens/sats_per_dollar.hpp" +#include "screens/market_cap.hpp" #include "screens/countdown.hpp" #include "screens/custom_text.hpp" #include "screens/halvingcountdown.hpp" + + #ifdef USE_UNIVERSAL_PIN #include #include