Configure Finnhub for Bitcoin/stocks, keep Yahoo for commodities/indices
This commit is contained in:
parent
fcde8cf66b
commit
16edb47b1d
1 changed files with 89 additions and 17 deletions
102
src/main.cpp
102
src/main.cpp
|
|
@ -30,6 +30,8 @@
|
||||||
#define MAX_INDICES 5
|
#define MAX_INDICES 5
|
||||||
#define MAX_TICKER_LEN 8
|
#define MAX_TICKER_LEN 8
|
||||||
|
|
||||||
|
#define FINNHUB_API_KEY "d74t3bpr01qg1eo6pln0d74t3bpr01qg1eo6plng"
|
||||||
|
|
||||||
class LGFX : public lgfx::LGFX_Device {
|
class LGFX : public lgfx::LGFX_Device {
|
||||||
public:
|
public:
|
||||||
lgfx::Bus_RGB _bus_instance;
|
lgfx::Bus_RGB _bus_instance;
|
||||||
|
|
@ -194,7 +196,7 @@ String formatPriceUS(double price, int decimals = 2, bool includeDollar = true)
|
||||||
return includeDollar ? "$" + result : result;
|
return includeDollar ? "$" + result : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fetchPrice(const char* symbol, double* result) {
|
bool fetchPriceYahoo(const char* symbol, double* result) {
|
||||||
WiFiClientSecure client;
|
WiFiClientSecure client;
|
||||||
client.setInsecure();
|
client.setInsecure();
|
||||||
|
|
||||||
|
|
@ -229,6 +231,39 @@ bool fetchPrice(const char* symbol, double* result) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fetchPriceFinnhub(const char* symbol, double* result) {
|
||||||
|
WiFiClientSecure client;
|
||||||
|
client.setInsecure();
|
||||||
|
|
||||||
|
HTTPClient http;
|
||||||
|
String url = "https://finnhub.io/api/v1/quote?symbol=" + String(symbol) + "&token=" + String(FINNHUB_API_KEY);
|
||||||
|
|
||||||
|
if (!http.begin(client, url)) return false;
|
||||||
|
|
||||||
|
http.setTimeout(15000);
|
||||||
|
|
||||||
|
int httpCode = http.GET();
|
||||||
|
if (httpCode != HTTP_CODE_OK) {
|
||||||
|
http.end();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String payload = http.getString();
|
||||||
|
http.end();
|
||||||
|
|
||||||
|
int idx = payload.indexOf("\"c\":");
|
||||||
|
if (idx == -1) return false;
|
||||||
|
|
||||||
|
int start = idx + 4;
|
||||||
|
int end = payload.indexOf(",", start);
|
||||||
|
if (end == -1) end = payload.indexOf("}", start);
|
||||||
|
if (end <= start) return false;
|
||||||
|
|
||||||
|
String priceStr = payload.substring(start, end);
|
||||||
|
*result = priceStr.toDouble();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void loadConfig() {
|
void loadConfig() {
|
||||||
preferences.begin("dashboard", true);
|
preferences.begin("dashboard", true);
|
||||||
|
|
||||||
|
|
@ -273,22 +308,23 @@ void saveConfig() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void updatePrices() {
|
void updatePrices() {
|
||||||
if (WiFi.status() != WL_CONNECTED) return;
|
if (WiFi.status() != WL_CONNECTED) return;
|
||||||
fetchPrice("BTC-USD", &btcPrice);
|
|
||||||
fetchPrice("GC=F", &goldPrice);
|
|
||||||
fetchPrice("SI=F", &silverPrice);
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_STOCKS; i++) {
|
fetchPriceFinnhub("BINANCE:BTCUSDT", &btcPrice);
|
||||||
if (strlen(stockTickers[i]) > 0) {
|
fetchPriceYahoo("GC=F", &goldPrice);
|
||||||
fetchPrice(stockTickers[i], &stockPrices[i]);
|
fetchPriceYahoo("SI=F", &silverPrice);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_INDICES; i++) {
|
for (int i = 0; i < MAX_STOCKS; i++) {
|
||||||
if (indexSelected[i] && strlen(indexTickers[i]) > 0) {
|
if (strlen(stockTickers[i]) > 0) {
|
||||||
fetchPrice(indexTickers[i], &indexPrices[i]);
|
fetchPriceFinnhub(stockTickers[i], &stockPrices[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_INDICES; i++) {
|
||||||
|
if (indexSelected[i] && strlen(indexTickers[i]) > 0) {
|
||||||
|
fetchPriceYahoo(indexTickers[i], &indexPrices[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawKeyboard(int y) {
|
void drawKeyboard(int y) {
|
||||||
|
|
@ -498,8 +534,16 @@ void drawDashboard() {
|
||||||
String wifiStatus = WiFi.status() == WL_CONNECTED ? "OK" : "OFFLINE";
|
String wifiStatus = WiFi.status() == WL_CONNECTED ? "OK" : "OFFLINE";
|
||||||
lcd.drawString("WiFi: " + wifiStatus, 20, SCREEN_HEIGHT - 20);
|
lcd.drawString("WiFi: " + wifiStatus, 20, SCREEN_HEIGHT - 20);
|
||||||
|
|
||||||
lcd.fillSmoothRoundRect(SCREEN_WIDTH - 160, SCREEN_HEIGHT - 36, 140, 32, 6, TFT_DARKGRAY);
|
int secondsLeft = (REFRESH_INTERVAL - (millis() - lastRefresh)) / 1000;
|
||||||
|
if (secondsLeft < 0) secondsLeft = 0;
|
||||||
|
int mins = secondsLeft / 60;
|
||||||
|
int secs = secondsLeft % 60;
|
||||||
|
char timeStr[8];
|
||||||
|
sprintf(timeStr, "%d:%02d", mins, secs);
|
||||||
lcd.setTextDatum(textdatum_t::middle_center);
|
lcd.setTextDatum(textdatum_t::middle_center);
|
||||||
|
lcd.drawString(String(timeStr), SCREEN_WIDTH / 2, SCREEN_HEIGHT - 20);
|
||||||
|
|
||||||
|
lcd.fillSmoothRoundRect(SCREEN_WIDTH - 160, SCREEN_HEIGHT - 36, 140, 32, 6, TFT_DARKGRAY);
|
||||||
lcd.drawString("CUSTOMIZE", SCREEN_WIDTH - 90, SCREEN_HEIGHT - 20);
|
lcd.drawString("CUSTOMIZE", SCREEN_WIDTH - 90, SCREEN_HEIGHT - 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -683,8 +727,15 @@ void showRefreshingMessage() {
|
||||||
lcd.fillSmoothRoundRect(0, SCREEN_HEIGHT - 40, SCREEN_WIDTH, 40, 8, TFT_ORANGE);
|
lcd.fillSmoothRoundRect(0, SCREEN_HEIGHT - 40, SCREEN_WIDTH, 40, 8, TFT_ORANGE);
|
||||||
lcd.setTextColor(TFT_WHITE, TFT_ORANGE);
|
lcd.setTextColor(TFT_WHITE, TFT_ORANGE);
|
||||||
lcd.setFont(&fonts::DejaVu18);
|
lcd.setFont(&fonts::DejaVu18);
|
||||||
|
lcd.setTextDatum(textdatum_t::middle_left);
|
||||||
|
String wifiStatus = WiFi.status() == WL_CONNECTED ? "OK" : "OFFLINE";
|
||||||
|
lcd.drawString("WiFi: " + wifiStatus, 20, SCREEN_HEIGHT - 20);
|
||||||
|
|
||||||
lcd.setTextDatum(textdatum_t::middle_center);
|
lcd.setTextDatum(textdatum_t::middle_center);
|
||||||
lcd.drawString("REFRESHING...", SCREEN_WIDTH / 2, SCREEN_HEIGHT - 20);
|
lcd.drawString("REFRESHING...", SCREEN_WIDTH / 2, SCREEN_HEIGHT - 20);
|
||||||
|
|
||||||
|
lcd.fillSmoothRoundRect(SCREEN_WIDTH - 160, SCREEN_HEIGHT - 36, 140, 32, 6, TFT_DARKGRAY);
|
||||||
|
lcd.drawString("CUSTOMIZE", SCREEN_WIDTH - 90, SCREEN_HEIGHT - 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshDataAndShow() {
|
void refreshDataAndShow() {
|
||||||
|
|
@ -769,6 +820,20 @@ void setup() {
|
||||||
drawDashboard();
|
drawDashboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawFooterCountdown() {
|
||||||
|
int secondsLeft = (REFRESH_INTERVAL - (millis() - lastRefresh)) / 1000;
|
||||||
|
if (secondsLeft < 0) secondsLeft = 0;
|
||||||
|
int mins = secondsLeft / 60;
|
||||||
|
int secs = secondsLeft % 60;
|
||||||
|
char timeStr[8];
|
||||||
|
sprintf(timeStr, "%d:%02d", mins, secs);
|
||||||
|
|
||||||
|
lcd.setFont(&fonts::DejaVu18);
|
||||||
|
lcd.setTextColor(TFT_WHITE, TFT_ORANGE);
|
||||||
|
lcd.setTextDatum(textdatum_t::middle_center);
|
||||||
|
lcd.drawString(String(timeStr), SCREEN_WIDTH / 2, SCREEN_HEIGHT - 20);
|
||||||
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
int32_t x, y;
|
int32_t x, y;
|
||||||
|
|
||||||
|
|
@ -810,7 +875,14 @@ void loop() {
|
||||||
delay(300);
|
delay(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long lastCountdownUpdate = 0;
|
||||||
|
if (currentScreen == SCREEN_DASHBOARD && millis() - lastCountdownUpdate >= 1000) {
|
||||||
|
lastCountdownUpdate = millis();
|
||||||
|
drawFooterCountdown();
|
||||||
|
}
|
||||||
|
|
||||||
if (currentScreen == SCREEN_DASHBOARD && millis() - lastRefresh > REFRESH_INTERVAL) {
|
if (currentScreen == SCREEN_DASHBOARD && millis() - lastRefresh > REFRESH_INTERVAL) {
|
||||||
|
showRefreshingMessage();
|
||||||
updatePrices();
|
updatePrices();
|
||||||
lastRefresh = millis();
|
lastRefresh = millis();
|
||||||
drawDashboard();
|
drawDashboard();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue