Refactor mining pool stats fetch to a class

This commit is contained in:
Djuri 2025-01-05 20:24:13 +01:00
parent c91428dd5f
commit ac13098824
Signed by: djuri
GPG key ID: 61B9B2DDE5AA3AC1
6 changed files with 100 additions and 88 deletions

View file

@ -105,7 +105,7 @@ void setup()
if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED)) if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED))
{ {
setupMiningPoolStatsFetchTask(); MiningPoolStatsFetch::getInstance().setup();
} }
ButtonHandler::setup(); ButtonHandler::setup();
@ -374,7 +374,7 @@ void setupPreferences()
if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED)) if (preferences.getBool("miningPoolStats", DEFAULT_MINING_POOL_STATS_ENABLED))
{ {
addScreenMapping(SCREEN_MINING_POOL_STATS_HASHRATE, "Mining Pool Hashrate"); addScreenMapping(SCREEN_MINING_POOL_STATS_HASHRATE, "Mining Pool Hashrate");
if (getMiningPool()->supportsDailyEarnings()) { if (MiningPoolStatsFetch::getInstance().getPool()->supportsDailyEarnings()) {
addScreenMapping(SCREEN_MINING_POOL_STATS_EARNINGS, "Mining Pool Earnings"); addScreenMapping(SCREEN_MINING_POOL_STATS_EARNINGS, "Mining Pool Earnings");
} }
} }

View file

@ -600,7 +600,7 @@ bool renderIcon(const uint dispNum, const String &text, bool partial)
} }
else if (text.endsWith("miningpool")) else if (text.endsWith("miningpool"))
{ {
LogoData logo = getMiningPoolLogo(); LogoData logo = MiningPoolStatsFetch::getInstance().getLogo();
if (logo.size == 0) if (logo.size == 0)
{ {

View file

@ -1,95 +1,98 @@
#include "mining_pool_stats_fetch.hpp" #include "mining_pool_stats_fetch.hpp"
TaskHandle_t miningPoolStatsFetchTaskHandle; void MiningPoolStatsFetch::taskWrapper(void* pvParameters) {
MiningPoolStatsFetch::getInstance().task();
std::string miningPoolName;
std::string miningPoolStatsHashrate;
int miningPoolStatsDailyEarnings;
std::string getMiningPoolStatsHashRate()
{
return miningPoolStatsHashrate;
} }
int getMiningPoolStatsDailyEarnings() void MiningPoolStatsFetch::downloadLogoTaskWrapper(void* pvParameters) {
{ MiningPoolStatsFetch::getInstance().downloadLogoTask();
return miningPoolStatsDailyEarnings;
} }
void taskMiningPoolStatsFetch(void *pvParameters) std::string MiningPoolStatsFetch::getHashRate() const {
{ return hashrate;
}
int MiningPoolStatsFetch::getDailyEarnings() const {
return dailyEarnings;
}
MiningPoolInterface* MiningPoolStatsFetch::getPool() {
if (!currentPool) {
std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str();
currentPool = PoolFactory::createPool(poolName);
}
return currentPool.get();
}
const MiningPoolInterface* MiningPoolStatsFetch::getPool() const {
return currentPool.get();
}
LogoData MiningPoolStatsFetch::getLogo() const {
if (const auto* pool = getPool()) {
return pool->getLogo();
}
return LogoData{};
}
void MiningPoolStatsFetch::task() {
std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str(); std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str();
auto poolInterface = PoolFactory::createPool(poolName); auto* poolInterface = getPool();
if (!poolInterface) return;
std::string poolUser = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER).c_str(); std::string poolUser = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER).c_str();
// Main stats fetching loop // Main stats fetching loop
for (;;) for (;;) {
{
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
HTTPClient http; HTTPClient http;
http.setUserAgent(USER_AGENT); http.setUserAgent(USER_AGENT);
poolInterface->setPoolUser(poolUser); poolInterface->setPoolUser(poolUser);
std::string apiUrl = poolInterface->getApiUrl(); std::string apiUrl = poolInterface->getApiUrl();
http.begin(apiUrl.c_str()); http.begin(apiUrl.c_str());
if (debugLogEnabled()) if (debugLogEnabled()) {
{
Serial.printf("Fetching mining pool stats from %s\r\n", apiUrl.c_str()); Serial.printf("Fetching mining pool stats from %s\r\n", apiUrl.c_str());
} }
poolInterface->prepareRequest(http); poolInterface->prepareRequest(http);
int httpCode = http.GET(); int httpCode = http.GET();
if (httpCode == 200) if (httpCode == 200) {
{
String payload = http.getString(); String payload = http.getString();
JsonDocument doc; JsonDocument doc;
deserializeJson(doc, payload); deserializeJson(doc, payload);
if (debugLogEnabled()) if (debugLogEnabled()) {
{
Serial.printf("Mining pool stats response: %s\r\n", payload.c_str()); Serial.printf("Mining pool stats response: %s\r\n", payload.c_str());
} }
PoolStats stats = poolInterface->parseResponse(doc); PoolStats stats = poolInterface->parseResponse(doc);
hashrate = stats.hashrate;
miningPoolStatsHashrate = stats.hashrate; if (debugLogEnabled()) {
if (debugLogEnabled())
{
Serial.printf("Mining pool stats parsed hashrate: %s\r\n", stats.hashrate.c_str()); Serial.printf("Mining pool stats parsed hashrate: %s\r\n", stats.hashrate.c_str());
} }
if (stats.dailyEarnings) dailyEarnings = stats.dailyEarnings ? *stats.dailyEarnings : 0;
{
miningPoolStatsDailyEarnings = *stats.dailyEarnings;
}
else
{
miningPoolStatsDailyEarnings = 0; // or any other default value
}
if (workQueue != nullptr && (ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE || ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_EARNINGS)) if (workQueue != nullptr && (ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE ||
{ ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_EARNINGS)) {
WorkItem priceUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0}; WorkItem priceUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0};
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
} }
} } else {
else Serial.print(F("Error retrieving mining pool data. HTTP status code: "));
{
Serial.print(
F("Error retrieving mining pool data. HTTP status code: "));
Serial.println(httpCode); Serial.println(httpCode);
} }
} }
} }
void downloadMiningPoolLogoTask(void *pvParameters) { void MiningPoolStatsFetch::downloadLogoTask() {
std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str(); std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str();
auto poolInterface = PoolFactory::createPool(poolName); auto* poolInterface = getPool();
PoolFactory::downloadPoolLogo(poolName, poolInterface.get()); if (!poolInterface) return;
PoolFactory::downloadPoolLogo(poolName, poolInterface);
// If we're on the mining pool stats screen, trigger a display update // If we're on the mining pool stats screen, trigger a display update
if (ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE) { if (ScreenHandler::getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE) {
@ -97,41 +100,22 @@ void downloadMiningPoolLogoTask(void *pvParameters) {
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY); xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
} }
xTaskNotifyGive(miningPoolStatsFetchTaskHandle); xTaskNotifyGive(taskHandle);
vTaskDelete(NULL); vTaskDelete(NULL);
} }
void setupMiningPoolStatsFetchTask() void MiningPoolStatsFetch::setup() {
{ xTaskCreate(downloadLogoTaskWrapper,
xTaskCreate(downloadMiningPoolLogoTask,
"logoDownload", "logoDownload",
(6 * 1024), (6 * 1024),
NULL, NULL,
tskIDLE_PRIORITY, tskIDLE_PRIORITY,
NULL); NULL);
xTaskCreate(taskMiningPoolStatsFetch, xTaskCreate(taskWrapper,
"miningPoolStatsFetch", "miningPoolStatsFetch",
(6 * 1024), (6 * 1024),
NULL, NULL,
tskIDLE_PRIORITY, tskIDLE_PRIORITY,
&miningPoolStatsFetchTaskHandle); &taskHandle);
}
std::unique_ptr<MiningPoolInterface>& getMiningPool()
{
static std::unique_ptr<MiningPoolInterface> currentMiningPool;
if (!currentMiningPool) {
std::string poolName = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str();
currentMiningPool = PoolFactory::createPool(poolName);
}
return currentMiningPool;
}
LogoData getMiningPoolLogo()
{
LogoData logo = getMiningPool()->getLogo();
return logo;
} }

View file

@ -2,18 +2,44 @@
#include <Arduino.h> #include <Arduino.h>
#include <HTTPClient.h> #include <HTTPClient.h>
#include "mining_pool/pool_factory.hpp" #include <utils.hpp>
#include <memory>
#include "lib/config.hpp" #include "lib/config.hpp"
#include "lib/shared.hpp" #include "lib/shared.hpp"
#include "lib/mining_pool/mining_pool_interface.hpp"
#include "mining_pool/pool_factory.hpp"
extern TaskHandle_t miningPoolStatsFetchTaskHandle; class MiningPoolStatsFetch {
public:
static MiningPoolStatsFetch& getInstance() {
static MiningPoolStatsFetch instance;
return instance;
}
void setupMiningPoolStatsFetchTask(); void setup();
void taskMiningPoolStatsFetch(void *pvParameters); std::string getHashRate() const;
int getDailyEarnings() const;
TaskHandle_t getTaskHandle() const { return taskHandle; }
static void taskWrapper(void* pvParameters);
static void downloadLogoTaskWrapper(void* pvParameters);
// Pool interface methods
MiningPoolInterface* getPool();
const MiningPoolInterface* getPool() const;
LogoData getLogo() const;
std::string getMiningPoolStatsHashRate(); private:
int getMiningPoolStatsDailyEarnings(); MiningPoolStatsFetch() = default;
~MiningPoolStatsFetch() = default;
MiningPoolStatsFetch(const MiningPoolStatsFetch&) = delete;
MiningPoolStatsFetch& operator=(const MiningPoolStatsFetch&) = delete;
std::unique_ptr<MiningPoolInterface>& getMiningPool(); void task();
LogoData getMiningPoolLogo(); void downloadLogoTask();
TaskHandle_t taskHandle = nullptr;
std::string hashrate;
int dailyEarnings = 0;
std::unique_ptr<MiningPoolInterface> currentPool;
};

View file

@ -231,9 +231,10 @@ void workerTask(void *pvParameters) {
currentScreenValue != SCREEN_MINING_POOL_STATS_EARNINGS) break; currentScreenValue != SCREEN_MINING_POOL_STATS_EARNINGS) break;
taskEpdContent = (currentScreenValue == SCREEN_MINING_POOL_STATS_HASHRATE) ? taskEpdContent = (currentScreenValue == SCREEN_MINING_POOL_STATS_HASHRATE) ?
parseMiningPoolStatsHashRate(getMiningPoolStatsHashRate(), *getMiningPool()) : parseMiningPoolStatsHashRate(MiningPoolStatsFetch::getInstance().getHashRate(), *MiningPoolStatsFetch::getInstance().getPool()) :
parseMiningPoolStatsDailyEarnings(getMiningPoolStatsDailyEarnings(), parseMiningPoolStatsDailyEarnings(MiningPoolStatsFetch::getInstance().getDailyEarnings(),
getMiningPool()->getDailyEarningsLabel(), *getMiningPool()); MiningPoolStatsFetch::getInstance().getPool()->getDailyEarningsLabel(),
*MiningPoolStatsFetch::getInstance().getPool());
setEpdContent(taskEpdContent); setEpdContent(taskEpdContent);
break; break;
} }

View file

@ -73,8 +73,9 @@ void IRAM_ATTR minuteTimerISR(void *arg) {
vTaskNotifyGiveFromISR(bitaxeHandle, &xHigherPriorityTaskWoken); vTaskNotifyGiveFromISR(bitaxeHandle, &xHigherPriorityTaskWoken);
} }
if (miningPoolStatsFetchTaskHandle != NULL) { TaskHandle_t miningPoolHandle = MiningPoolStatsFetch::getInstance().getTaskHandle();
vTaskNotifyGiveFromISR(miningPoolStatsFetchTaskHandle, &xHigherPriorityTaskWoken); if (miningPoolHandle != NULL) {
vTaskNotifyGiveFromISR(miningPoolHandle, &xHigherPriorityTaskWoken);
} }
if (xHigherPriorityTaskWoken == pdTRUE) { if (xHigherPriorityTaskWoken == pdTRUE) {