forked from btclock/btclock_v3
rebuilt with larger partitions
This commit is contained in:
parent
ae2e6656df
commit
1bd465b33a
16 changed files with 782 additions and 8 deletions
|
@ -95,6 +95,11 @@ void setup()
|
|||
setupBitaxeFetchTask();
|
||||
}
|
||||
|
||||
if (preferences.getBool("miningPoolStatsEnabled", DEFAULT_MINING_POOL_STATS_ENABLED))
|
||||
{
|
||||
setupMiningPoolStatsFetchTask();
|
||||
}
|
||||
|
||||
setupButtonTask();
|
||||
setupOTA();
|
||||
|
||||
|
@ -331,6 +336,11 @@ void setupPreferences()
|
|||
addScreenMapping(SCREEN_BITAXE_HASHRATE, "BitAxe Hashrate");
|
||||
addScreenMapping(SCREEN_BITAXE_BESTDIFF, "BitAxe Best Difficulty");
|
||||
}
|
||||
|
||||
if (preferences.getBool("miningPoolStatsEnabled", DEFAULT_MINING_POOL_STATS_ENABLED))
|
||||
{
|
||||
addScreenMapping(SCREEN_MINING_POOL_STATS_HASHRATE, "Mining Pool Hashrate");
|
||||
}
|
||||
}
|
||||
|
||||
String replaceAmbiguousChars(String input)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "lib/ota.hpp"
|
||||
#include "lib/nostr_notify.hpp"
|
||||
#include "lib/bitaxe_fetch.hpp"
|
||||
#include "lib/mining_pool_stats_fetch.hpp"
|
||||
|
||||
#include "lib/v2_notify.hpp"
|
||||
|
||||
|
|
|
@ -58,6 +58,13 @@
|
|||
#define DEFAULT_BITAXE_ENABLED false
|
||||
#define DEFAULT_BITAXE_HOSTNAME "bitaxe1"
|
||||
|
||||
#define MINING_POOL_NAME_OCEAN "ocean"
|
||||
#define MINING_POOL_NAME_BRAIINS "braiins"
|
||||
|
||||
#define DEFAULT_MINING_POOL_STATS_ENABLED true
|
||||
#define DEFAULT_MINING_POOL_NAME MINING_POOL_NAME_OCEAN
|
||||
#define DEFAULT_MINING_POOL_USER "38Qkkei3SuF1Eo45BaYmRHUneRD54yyTFy" // Random actual Ocean hasher
|
||||
|
||||
#define DEFAULT_ZAP_NOTIFY_ENABLED false
|
||||
#define DEFAULT_ZAP_NOTIFY_PUBKEY "b5127a08cf33616274800a4387881a9f98e04b9c37116e92de5250498635c422"
|
||||
#define DEFAULT_LED_FLASH_ON_ZAP true
|
||||
|
|
|
@ -613,6 +613,12 @@ void renderIcon(const uint dispNum, const String &text, bool partial)
|
|||
else if (text.endsWith("bitaxe")) {
|
||||
iconIndex = 4;
|
||||
}
|
||||
else if (text.endsWith("ocean_logo")) {
|
||||
iconIndex = 5;
|
||||
}
|
||||
else if (text.endsWith("braiins_logo")) {
|
||||
iconIndex = 6;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
120
src/lib/mining_pool_stats_fetch.cpp
Normal file
120
src/lib/mining_pool_stats_fetch.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#include "mining_pool_stats_fetch.hpp"
|
||||
|
||||
TaskHandle_t miningPoolStatsFetchTaskHandle;
|
||||
|
||||
std::string miningPoolStatsHashrate;
|
||||
std::string miningPoolStatsBestDiff;
|
||||
|
||||
std::string getMiningPoolStatsHashRate()
|
||||
{
|
||||
return miningPoolStatsHashrate;
|
||||
}
|
||||
|
||||
|
||||
void taskMiningPoolStatsFetch(void *pvParameters)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
HTTPClient http;
|
||||
http.setUserAgent(USER_AGENT);
|
||||
String miningPoolStatsApiUrl;
|
||||
|
||||
// TODO: Remove when webui gets proper update
|
||||
Serial.println("FORCING miningPoolUser");
|
||||
preferences.putString("miningPoolName", MINING_POOL_NAME_OCEAN);
|
||||
|
||||
Serial.println("miningPoolName: \"" + preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME) + "\"");
|
||||
Serial.println("miningPoolUser: \"" + preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER) + "\"");
|
||||
|
||||
std::string httpHeaderKey = "";
|
||||
std::string httpHeaderValue;
|
||||
if (preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME) == MINING_POOL_NAME_OCEAN) {
|
||||
miningPoolStatsApiUrl = "https://api.ocean.xyz/v1/statsnap/" + preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER);
|
||||
Serial.println(miningPoolStatsApiUrl);
|
||||
|
||||
}
|
||||
else if (preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME) == MINING_POOL_NAME_BRAIINS) {
|
||||
miningPoolStatsApiUrl = "https://pool.braiins.com/accounts/profile/json/btc/";
|
||||
httpHeaderKey = "Pool-Auth-Token";
|
||||
httpHeaderValue = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER).c_str();
|
||||
Serial.println(miningPoolStatsApiUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.println("Unknown mining pool: \"" + preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME) + "\"");
|
||||
continue;
|
||||
}
|
||||
|
||||
http.begin(miningPoolStatsApiUrl.c_str());
|
||||
|
||||
if (httpHeaderKey.length() > 0) {
|
||||
http.addHeader(httpHeaderKey.c_str(), httpHeaderValue.c_str());
|
||||
}
|
||||
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode == 200)
|
||||
{
|
||||
String payload = http.getString();
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, payload);
|
||||
|
||||
Serial.println(doc.as<String>());
|
||||
|
||||
if (preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME) == MINING_POOL_NAME_OCEAN) {
|
||||
Serial.println(doc["result"].as<String>());
|
||||
Serial.println(doc["result"]["hashrate_300s"].as<String>());
|
||||
miningPoolStatsHashrate = doc["result"]["hashrate_300s"].as<std::string>();
|
||||
}
|
||||
else if (preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME) == MINING_POOL_NAME_BRAIINS) {
|
||||
// Reports hashrate in specific hashrate units (e.g. Gh/s); we want raw total hashes per second.
|
||||
std::string hashrateUnit = doc["btc"]["hash_rate_unit"].as<std::string>();
|
||||
Serial.println(doc["btc"]["hash_rate_unit"].as<String>());
|
||||
int multiplier = 0;
|
||||
if (hashrateUnit == "Zh/s") {
|
||||
multiplier = 21;
|
||||
} else if (hashrateUnit == "Eh/s") {
|
||||
multiplier = 18;
|
||||
} else if (hashrateUnit == "Ph/s") {
|
||||
multiplier = 15;
|
||||
} else if (hashrateUnit == "Th/s") {
|
||||
multiplier = 12;
|
||||
} else if (hashrateUnit == "Gh/s") {
|
||||
multiplier = 9;
|
||||
} else if (hashrateUnit == "Mh/s") {
|
||||
multiplier = 6;
|
||||
} else if (hashrateUnit == "Kh/s") {
|
||||
multiplier = 3;
|
||||
}
|
||||
|
||||
// Add zeroes to pad to a full h/s output
|
||||
miningPoolStatsHashrate = std::to_string(static_cast<int>(std::round(doc["btc"]["hash_rate_5m"].as<float>()))) + std::string(multiplier, '0');
|
||||
Serial.println(miningPoolStatsHashrate.c_str());
|
||||
}
|
||||
|
||||
// if (workQueue != nullptr && (getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE || getCurrentScreen() == SCREEN_MINING_POOL_STATS_BESTDIFF))
|
||||
if (workQueue != nullptr && (getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE))
|
||||
{
|
||||
WorkItem priceUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0};
|
||||
xQueueSend(workQueue, &priceUpdate, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Serial.print(
|
||||
F("Error retrieving mining pool data. HTTP status code: "));
|
||||
Serial.println(httpCode);
|
||||
Serial.println(miningPoolStatsApiUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setupMiningPoolStatsFetchTask()
|
||||
{
|
||||
xTaskCreate(taskMiningPoolStatsFetch, "miningPoolStatsFetch", (6 * 1024), NULL, tskIDLE_PRIORITY,
|
||||
&miningPoolStatsFetchTaskHandle);
|
||||
|
||||
xTaskNotifyGive(miningPoolStatsFetchTaskHandle);
|
||||
}
|
15
src/lib/mining_pool_stats_fetch.hpp
Normal file
15
src/lib/mining_pool_stats_fetch.hpp
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <HTTPClient.h>
|
||||
|
||||
#include "lib/config.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
|
||||
extern TaskHandle_t miningPoolStatsFetchTaskHandle;
|
||||
|
||||
void setupMiningPoolStatsFetchTask();
|
||||
void taskMiningPoolStatsFetch(void *pvParameters);
|
||||
|
||||
std::string getMiningPoolStatsHashRate();
|
||||
// std::string getMiningPoolStatsBestDiff();
|
|
@ -33,9 +33,19 @@ void workerTask(void *pvParameters) {
|
|||
parseBitaxeBestDiff(getBitaxeBestDiff());
|
||||
}
|
||||
setEpdContent(taskEpdContent);
|
||||
|
||||
break;
|
||||
}
|
||||
case TASK_MINING_POOL_STATS_UPDATE: {
|
||||
if (getCurrentScreen() == SCREEN_MINING_POOL_STATS_HASHRATE) {
|
||||
taskEpdContent =
|
||||
parseMiningPoolStatsHashRate(preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME).c_str(), getMiningPoolStatsHashRate());
|
||||
// } else if (getCurrentScreen() == SCREEN_BITAXE_BESTDIFF) {
|
||||
// taskEpdContent =
|
||||
// parseBitaxeBestDiff(getBitaxeBestDiff());
|
||||
}
|
||||
setEpdContent(taskEpdContent);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TASK_PRICE_UPDATE: {
|
||||
uint currency = getCurrentCurrency();
|
||||
uint price = getPrice(currency);
|
||||
|
@ -179,6 +189,16 @@ void setCurrentScreen(uint newScreen) {
|
|||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SCREEN_MINING_POOL_STATS_HASHRATE: {
|
||||
if (preferences.getBool("miningPoolStatsEnabled", DEFAULT_MINING_POOL_STATS_ENABLED)) {
|
||||
WorkItem miningPoolStatsUpdate = {TASK_MINING_POOL_STATS_UPDATE, 0};
|
||||
xQueueSend(workQueue, &miningPoolStatsUpdate, portMAX_DELAY);
|
||||
} else {
|
||||
setCurrentScreen(SCREEN_BLOCK_HEIGHT);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <data_handler.hpp>
|
||||
#include <bitaxe_handler.hpp>
|
||||
#include <mining_pool_stats_handler.hpp>
|
||||
|
||||
#include "lib/epd.hpp"
|
||||
#include "lib/shared.hpp"
|
||||
|
@ -23,7 +24,8 @@ typedef enum {
|
|||
TASK_BLOCK_UPDATE,
|
||||
TASK_FEE_UPDATE,
|
||||
TASK_TIME_UPDATE,
|
||||
TASK_BITAXE_UPDATE
|
||||
TASK_BITAXE_UPDATE,
|
||||
TASK_MINING_POOL_STATS_UPDATE
|
||||
} TaskType;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -60,6 +60,8 @@ const PROGMEM int SCREEN_MARKET_CAP = 30;
|
|||
const PROGMEM int SCREEN_BITAXE_HASHRATE = 80;
|
||||
const PROGMEM int SCREEN_BITAXE_BESTDIFF = 81;
|
||||
|
||||
const PROGMEM int SCREEN_MINING_POOL_STATS_HASHRATE = 85;
|
||||
|
||||
const PROGMEM int SCREEN_COUNTDOWN = 98;
|
||||
const PROGMEM int SCREEN_CUSTOM = 99;
|
||||
const int SCREEN_COUNT = 7;
|
||||
|
|
|
@ -72,6 +72,10 @@ void IRAM_ATTR minuteTimerISR(void *arg) {
|
|||
vTaskNotifyGiveFromISR(bitaxeFetchTaskHandle, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
if (miningPoolStatsFetchTaskHandle != NULL) {
|
||||
vTaskNotifyGiveFromISR(miningPoolStatsFetchTaskHandle, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
|
|
@ -510,7 +510,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
|
|||
settings["timePerScreen"].as<uint>() * 60);
|
||||
}
|
||||
|
||||
String strSettings[] = {"hostnamePrefix", "mempoolInstance", "nostrPubKey", "nostrRelay", "bitaxeHostname", "nostrZapPubkey", "httpAuthUser", "httpAuthPass", "gitReleaseUrl"};
|
||||
String strSettings[] = {"hostnamePrefix", "mempoolInstance", "nostrPubKey", "nostrRelay", "bitaxeHostname", "miningPoolName", "miningPoolUser", "nostrZapPubkey", "httpAuthUser", "httpAuthPass", "gitReleaseUrl"};
|
||||
|
||||
for (String setting : strSettings)
|
||||
{
|
||||
|
@ -549,7 +549,7 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
|
|||
"mowMode", "suffixShareDot", "flOffWhenDark",
|
||||
"flAlwaysOn", "flDisable", "flFlashOnUpd",
|
||||
"mempoolSecure", "useNostr", "bitaxeEnabled",
|
||||
"verticalDesc",
|
||||
"miningPoolStatsEnabled", "verticalDesc",
|
||||
"nostrZapNotify", "stagingSource", "httpAuthEnabled"};
|
||||
|
||||
for (String setting : boolSettings)
|
||||
|
@ -714,6 +714,10 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
|
|||
root["bitaxeEnabled"] = preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED);
|
||||
root["bitaxeHostname"] = preferences.getString("bitaxeHostname", DEFAULT_BITAXE_HOSTNAME);
|
||||
|
||||
root["miningPoolStatsEnabled"] = preferences.getBool("miningPoolStatsEnabled", DEFAULT_MINING_POOL_STATS_ENABLED);
|
||||
root["miningPoolName"] = preferences.getString("miningPoolName", DEFAULT_MINING_POOL_NAME);
|
||||
root["miningPoolUser"] = preferences.getString("miningPoolUser", DEFAULT_MINING_POOL_USER);
|
||||
|
||||
root["httpAuthEnabled"] = preferences.getBool("httpAuthEnabled", DEFAULT_HTTP_AUTH_ENABLED);
|
||||
root["httpAuthUser"] = preferences.getString("httpAuthUser", DEFAULT_HTTP_AUTH_USERNAME);
|
||||
root["httpAuthPass"] = preferences.getString("httpAuthPass", DEFAULT_HTTP_AUTH_PASSWORD);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue