Improve data source selection, clean up unused preferences
All checks were successful
BTClock CI / build (push) Successful in 27m2s
BTClock CI / merge (map[name:btclock_v8 version:esp32s3], 213epd) (push) Successful in 21s
BTClock CI / merge (map[name:btclock_rev_b version:esp32s3], 213epd) (push) Successful in 36s
BTClock CI / merge (map[name:lolin_s3_mini version:esp32s3], 213epd) (push) Successful in 20s
BTClock CI / merge (map[name:lolin_s3_mini version:esp32s3], 29epd) (push) Successful in 30s
BTClock CI / release (push) Successful in 12s

This commit is contained in:
Djuri Baars 2024-12-28 18:19:31 +01:00
parent bc3e5afe51
commit 64e518bf58
13 changed files with 155 additions and 104 deletions

2
data

@ -1 +1 @@
Subproject commit 2ce53eb499e00a990be5cb0ea078e146f467ceb4
Subproject commit 4057e1875508b47d876478d97cff544213fd63d4

View file

@ -82,11 +82,6 @@ void setupBlockNotify()
xQueueSend(workQueue, &blockUpdate, portMAX_DELAY);
}
if (!preferences.getBool("fetchEurPrice", DEFAULT_FETCH_EUR_PRICE) && preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE))
{
return;
}
// std::strcpy(wsServer, String("wss://" + mempoolInstance +
// "/api/v1/ws").c_str());

View file

@ -25,6 +25,23 @@ void addScreenMapping(int value, const char *name)
screenMappings.push_back({value, name});
}
void setupDataSource()
{
DataSourceType dataSource = getDataSource();
bool zapNotifyEnabled = preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED);
// Setup Nostr if it's either the data source or zap notifications are enabled
if (dataSource == NOSTR_SOURCE || zapNotifyEnabled) {
setupNostrNotify(dataSource == NOSTR_SOURCE, zapNotifyEnabled);
setupNostrTask();
}
// Setup other data sources if Nostr is not the data source
if (dataSource != NOSTR_SOURCE) {
xTaskCreate(setupWebsocketClients, "setupWebsocketClients", 8192, NULL,
tskIDLE_PRIORITY, NULL);
}
}
void setup()
{
setupPreferences();
@ -78,17 +95,8 @@ void setup()
setupTasks();
setupTimers();
if (preferences.getBool("useNostr", DEFAULT_USE_NOSTR) || preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED))
{
setupNostrNotify(preferences.getBool("useNostr", DEFAULT_USE_NOSTR), preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED));
setupNostrTask();
}
if (!preferences.getBool("useNostr", DEFAULT_USE_NOSTR))
{
xTaskCreate(setupWebsocketClients, "setupWebsocketClients", 8192, NULL,
tskIDLE_PRIORITY, NULL);
}
// Setup data sources (includes Nostr zap notifications if enabled)
setupDataSource();
if (preferences.getBool("bitaxeEnabled", DEFAULT_BITAXE_ENABLED))
{
@ -288,22 +296,26 @@ void setupPreferences()
preferences.putBool("enableDebugLog", DEFAULT_ENABLE_DEBUG_LOG);
}
if (!preferences.isKey("ceEnabled")) {
preferences.putBool("ceEnabled", DEFAULT_CUSTOM_ENDPOINT_ENABLED);
if (!preferences.isKey("dataSource")) {
preferences.putUChar("dataSource", DEFAULT_DATA_SOURCE);
}
if (!preferences.isKey("ceEndpoint")) {
preferences.putString("ceEndpoint", DEFAULT_CUSTOM_ENDPOINT);
// Initialize custom endpoint settings if not set
if (!preferences.isKey("customEndpoint")) {
preferences.putString("customEndpoint", DEFAULT_CUSTOM_ENDPOINT);
}
if (!preferences.isKey("ceDisableSSL")) {
preferences.putBool("ceDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL);
if (!preferences.isKey("customEndpointDisableSSL")) {
preferences.putBool("customEndpointDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL);
}
if (preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE))
// Set currency based on data source
DataSourceType dataSource = static_cast<DataSourceType>(preferences.getUChar("dataSource", DEFAULT_DATA_SOURCE));
if (dataSource == BTCLOCK_SOURCE || dataSource == CUSTOM_SOURCE) {
ScreenHandler::setCurrentCurrency(preferences.getUChar("lastCurrency", CURRENCY_USD));
else
} else {
ScreenHandler::setCurrentCurrency(CURRENCY_USD);
}
if (!preferences.isKey("flDisable")) {
preferences.putBool("flDisable", isWhiteVersion() ? false : true);
@ -377,11 +389,13 @@ String replaceAmbiguousChars(String input)
void setupWebsocketClients(void *pvParameters)
{
if (preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE))
DataSourceType dataSource = getDataSource();
if (dataSource == BTCLOCK_SOURCE || dataSource == CUSTOM_SOURCE)
{
V2Notify::setupV2Notify();
}
else
else if (dataSource == THIRD_PARTY_SOURCE)
{
setupBlockNotify();
setupPriceNotify();
@ -788,3 +802,11 @@ bool debugLogEnabled()
{
return preferences.getBool("enableDebugLog", DEFAULT_ENABLE_DEBUG_LOG);
}
DataSourceType getDataSource() {
return static_cast<DataSourceType>(preferences.getUChar("dataSource", DEFAULT_DATA_SOURCE));
}
void setDataSource(DataSourceType source) {
preferences.putUChar("dataSource", static_cast<uint8_t>(source));
}

View file

@ -31,6 +31,9 @@
#include "BH1750.h"
#endif
#include "shared.hpp"
#include "defaults.hpp"
#define NTP_SERVER "pool.ntp.org"
#define DEFAULT_TIME_OFFSET_SECONDS 3600
#ifndef MCP_DEV_ADDR
@ -87,4 +90,14 @@ int findScreenIndexByValue(int value);
String replaceAmbiguousChars(String input);
const char* getFirmwareFilename();
const char* getWebUiFilename();
// void loadIcons();
// void loadIcons();
extern Preferences preferences;
extern MCP23017 mcp1;
#ifdef IS_BTCLOCK_V8
extern MCP23017 mcp2;
#endif
// Expose DataSourceType enum
extern DataSourceType getDataSource();
extern void setDataSource(DataSourceType source);

View file

@ -1,4 +1,6 @@
#define INITIAL_BLOCK_HEIGHT 851500
#pragma once
#define INITIAL_BLOCK_HEIGHT 876600
#define INITIAL_LAST_PRICE 50000
#define DEFAULT_TX_POWER 0
@ -16,16 +18,11 @@
#define DEFAULT_SUFFIX_PRICE false
#define DEFAULT_DISABLE_LEDS false
#define DEFAULT_DISABLE_FL false
#define DEFAULT_OWN_DATA_SOURCE true
#define DEFAULT_CUSTOM_SOURCE false
#define DEFAULT_CUSTOM_EP "ws-staging.btclock.dev"
#define DEFAULT_CUSTOM_SSL true
#define DEFAULT_MOW_MODE false
#define DEFAULT_SUFFIX_SHARE_DOT false
#define DEFAULT_V2_SOURCE_CURRENCY CURRENCY_USD
#define DEFAULT_TIME_OFFSET_SECONDS 3600
#define DEFAULT_HOSTNAME_PREFIX "btclock"
@ -83,8 +80,16 @@
#define DEFAULT_ENABLE_DEBUG_LOG false
#define DEFAULT_DISABLE_FL false
#define DEFAULT_OWN_DATA_SOURCE true
#define DEFAULT_CUSTOM_ENDPOINT_ENABLED false
#define DEFAULT_CUSTOM_ENDPOINT "ws-staging.btclock.dev"
#define DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL false
#define DEFAULT_MOW_MODE false
// Define data source types
enum DataSourceType {
BTCLOCK_SOURCE = 0, // BTClock's own data source
THIRD_PARTY_SOURCE = 1, // Third party data sources like mempool.space
NOSTR_SOURCE = 2, // Nostr data source
CUSTOM_SOURCE = 3 // Custom data source endpoint
};
#define DEFAULT_DATA_SOURCE BTCLOCK_SOURCE

View file

@ -550,7 +550,7 @@ bool renderIcon(const uint dispNum, const String &text, bool partial)
LogoData logo = getMiningPoolLogo();
if (logo.size == 0) {
Serial.println("No logo found");
Serial.println(F("No logo found"));
return false;
}

View file

@ -76,7 +76,8 @@ void setupNostrNotify(bool asDatasource, bool zapNotify)
void nostrTask(void *pvParameters)
{
if(preferences.getBool("useNostr", DEFAULT_USE_NOSTR)) {
DataSourceType dataSource = getDataSource();
if(dataSource == NOSTR_SOURCE) {
int blockFetch = getBlockFetch();
processNewBlock(blockFetch);
}

View file

@ -181,7 +181,7 @@ int downloadUpdateHandler(char updateType)
String expectedSHA256 = downloadSHA256(latestRelease.checksumUrl);
if (expectedSHA256.isEmpty())
{
Serial.println("Failed to get SHA256 checksum. Aborting update.");
Serial.println(F("Failed to get SHA256 checksum. Aborting update."));
return false;
}
@ -217,7 +217,7 @@ int downloadUpdateHandler(char updateType)
if (bytesRead != contentLength)
{
Serial.println("Failed to read entire firmware");
Serial.println(F("Failed to read entire firmware"));
free(firmware);
return false;
}
@ -225,14 +225,14 @@ int downloadUpdateHandler(char updateType)
// Calculate SHA256
String calculated_sha256 = calculateSHA256(firmware, contentLength);
Serial.print("Calculated checksum: ");
Serial.print(F("Calculated checksum: "));
Serial.println(calculated_sha256);
Serial.print("Expected checksum: ");
Serial.print(F("Expected checksum: "));
Serial.println(expectedSHA256);
if (calculated_sha256 != expectedSHA256)
{
Serial.println("Checksum mismatch. Aborting update.");
Serial.println(F("Checksum mismatch. Aborting update."));
free(firmware);
return false;
}
@ -258,15 +258,15 @@ int downloadUpdateHandler(char updateType)
if (Update.end())
{
Serial.println("OTA done!");
Serial.println(F("OTA done!"));
if (Update.isFinished())
{
Serial.println("Update successfully completed. Rebooting.");
Serial.println(F("Update successfully completed. Rebooting."));
// ESP.restart();
}
else
{
Serial.println("Update not finished? Something went wrong!");
Serial.println(F("Update not finished? Something went wrong!"));
free(firmware);
return 503;
}
@ -280,14 +280,14 @@ int downloadUpdateHandler(char updateType)
}
else
{
Serial.println("Not enough space to begin OTA");
Serial.println(F("Not enough space to begin OTA"));
free(firmware);
return 503;
}
}
else
{
Serial.println("Invalid content length");
Serial.println(F("Invalid content length"));
return 503;
}
}
@ -337,7 +337,7 @@ void updateWebUi(String latestRelease, int command)
Serial.println(calculated_sha256);
if ((command == U_FLASH && expectedSHA256.equals(calculated_sha256)) || command == U_SPIFFS)
{
Serial.println("Checksum verified. Proceeding with update.");
Serial.println(F("Checksum verified. Proceeding with update."));
Update.onProgress(onOTAProgress);
@ -348,38 +348,38 @@ void updateWebUi(String latestRelease, int command)
Update.write(buffer, contentLength);
if (Update.end())
{
Serial.println("Update complete. Rebooting.");
Serial.println(F("Update complete. Rebooting."));
ESP.restart();
}
else
{
Serial.println("Error in update process.");
Serial.println(F("Error in update process."));
}
}
else
{
Serial.println("Not enough space to begin OTA");
Serial.println(F("Not enough space to begin OTA"));
}
}
else
{
Serial.println("Checksum mismatch. Aborting update.");
Serial.println(F("Checksum mismatch. Aborting update."));
}
}
else
{
Serial.println("Error downloading firmware");
Serial.println(F("Error downloading firmware"));
}
free(buffer);
}
else
{
Serial.println("Not enough memory to allocate buffer");
Serial.println(F("Not enough memory to allocate buffer"));
}
}
else
{
Serial.println("Invalid content length");
Serial.println(F("Invalid content length"));
}
}
else
@ -417,7 +417,7 @@ String downloadSHA256(const String &sha256Url)
{
if (sha256Url.isEmpty())
{
Serial.println("Failed to get SHA256 file URL");
Serial.println(F("Failed to get SHA256 file URL"));
return "";
}

View file

@ -1,8 +1,5 @@
#include "price_notify.hpp"
const char *wsOwnServerPrice = "wss://ws.btclock.dev/ws?assets=bitcoin";
const char *wsOwnServerV2 = "wss://ws-staging.btclock.dev/api/v2/ws";
const char *wsServerPrice = "wss://ws.coincap.io/prices?assets=bitcoin";
// WebsocketsClient client;
@ -17,19 +14,12 @@ WebSocketsClient priceNotifyWs;
void setupPriceNotify()
{
if (preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE))
{
config = {.uri = wsOwnServerPrice,
.user_agent = USER_AGENT};
}
else
{
config = {.uri = wsServerPrice,
.user_agent = USER_AGENT};
config.cert_pem = isrg_root_x1cert;
config = {.uri = wsServerPrice,
.user_agent = USER_AGENT};
config.cert_pem = isrg_root_x1cert;
config.task_stack = (6*1024);
config.task_stack = (6*1024);
}
clientPrice = esp_websocket_client_init(&config);
esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY,
@ -86,10 +76,6 @@ void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base,
break;
case WEBSOCKET_EVENT_DATA:
onWebsocketPriceMessage(data);
if (preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE))
{
onWebsocketBlockMessage(data);
}
break;
case WEBSOCKET_EVENT_ERROR:
Serial.println(F("Price WS Connnection error"));

View file

@ -85,7 +85,7 @@ bool ScreenHandler::isCurrencySpecific(uint screen) {
}
bool ScreenHandler::handleCurrencyRotation(bool forward) {
if (preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE) && isCurrencySpecific(getCurrentScreen())) {
if ((getDataSource() == BTCLOCK_SOURCE || getDataSource() == CUSTOM_SOURCE) && isCurrencySpecific(getCurrentScreen())) {
std::vector<std::string> ac = getActiveCurrencies();
if (ac.empty()) return false;

View file

@ -13,7 +13,7 @@ namespace V2Notify
void setupV2Notify()
{
String hostname = "ws.btclock.dev";
if (preferences.getBool("ceEnabled", DEFAULT_CUSTOM_ENDPOINT_ENABLED))
if (getDataSource() == CUSTOM_SOURCE)
{
Serial.println(F("Connecting to custom source"));
hostname = preferences.getString("ceEndpoint", DEFAULT_CUSTOM_ENDPOINT);

View file

@ -5,17 +5,17 @@ static const char* JSON_CONTENT = "application/json";
static const char *const PROGMEM strSettings[] = {
"hostnamePrefix", "mempoolInstance", "nostrPubKey", "nostrRelay", "bitaxeHostname", "miningPoolName", "miningPoolUser", "nostrZapPubkey", "httpAuthUser", "httpAuthPass", "gitReleaseUrl", "poolLogosUrl", "ceEndpoint"};
static const char *const PROGMEM uintSettings[] = {"minSecPriceUpd", "fullRefreshMin", "ledBrightness", "flMaxBrightness", "flEffectDelay", "luxLightToggle", "wpTimeout", "srcV2Currency"};
static const char *const PROGMEM uintSettings[] = {"minSecPriceUpd", "fullRefreshMin", "ledBrightness", "flMaxBrightness", "flEffectDelay", "luxLightToggle", "wpTimeout"};
static const char *const PROGMEM boolSettings[] = {"fetchEurPrice", "ledTestOnPower", "ledFlashOnUpd",
static const char *const PROGMEM boolSettings[] = {"ledTestOnPower", "ledFlashOnUpd",
"mdnsEnabled", "otaEnabled", "stealFocus",
"mcapBigChar", "useSatsSymbol", "useBlkCountdown",
"suffixPrice", "disableLeds", "ownDataSource",
"suffixPrice", "disableLeds",
"mowMode", "suffixShareDot", "flOffWhenDark",
"flAlwaysOn", "flDisable", "flFlashOnUpd",
"mempoolSecure", "useNostr", "bitaxeEnabled",
"mempoolSecure", "bitaxeEnabled",
"miningPoolStats", "verticalDesc",
"nostrZapNotify", "ceEnabled", "httpAuthEnabled",
"nostrZapNotify", "httpAuthEnabled",
"enableDebugLog", "ceDisableSSL"};
AsyncWebServer server(80);
@ -581,6 +581,29 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
}
}
// Handle data source setting
if (settings["dataSource"].is<uint8_t>()) {
uint8_t dataSource = settings["dataSource"].as<uint8_t>();
if (dataSource <= CUSTOM_SOURCE) { // Validate including custom source
preferences.putUChar("dataSource", dataSource);
Serial.printf("Setting dataSource to %d\r\n", dataSource);
settingsChanged = true;
}
}
// Handle custom endpoint settings
if (settings["customEndpoint"].is<String>()) {
preferences.putString("customEndpoint", settings["customEndpoint"].as<String>());
Serial.printf("Setting customEndpoint to %s\r\n", settings["customEndpoint"].as<String>().c_str());
settingsChanged = true;
}
if (settings["customEndpointDisableSSL"].is<bool>()) {
preferences.putBool("customEndpointDisableSSL", settings["customEndpointDisableSSL"].as<bool>());
Serial.printf("Setting customEndpointDisableSSL to %d\r\n", settings["customEndpointDisableSSL"].as<bool>());
settingsChanged = true;
}
request->send(HTTP_OK);
if (settingsChanged)
{
@ -590,14 +613,17 @@ void onApiSettingsPatch(AsyncWebServerRequest *request, JsonVariant &json)
void onApiRestart(AsyncWebServerRequest *request)
{
request->onDisconnect([]() {
delay(500);
noInterrupts();
esp_restart();
});
request->send(HTTP_OK);
if (events.count())
events.send("closing");
delay(500);
esp_restart();
}
void onApiIdentify(AsyncWebServerRequest *request)
@ -634,10 +660,25 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
preferences.getUInt("fullRefreshMin", DEFAULT_MINUTES_FULL_REFRESH);
root["wpTimeout"] = preferences.getUInt("wpTimeout", DEFAULT_WP_TIMEOUT);
root["tzOffset"] = preferences.getInt("gmtOffset", DEFAULT_TIME_OFFSET_SECONDS) / 60;
root["mempoolInstance"] =
preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE);
// Add data source settings
root["dataSource"] = preferences.getUChar("dataSource", DEFAULT_DATA_SOURCE);
// Mempool settings (only used for THIRD_PARTY_SOURCE)
root["mempoolInstance"] = preferences.getString("mempoolInstance", DEFAULT_MEMPOOL_INSTANCE);
root["mempoolSecure"] = preferences.getBool("mempoolSecure", DEFAULT_MEMPOOL_SECURE);
root["useNostr"] = preferences.getBool("useNostr", DEFAULT_USE_NOSTR);
// Nostr settings (used for NOSTR_SOURCE or when zapNotify is enabled)
root["nostrPubKey"] = preferences.getString("nostrPubKey", DEFAULT_NOSTR_NPUB);
root["nostrRelay"] = preferences.getString("nostrRelay", DEFAULT_NOSTR_RELAY);
root["nostrZapNotify"] = preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED);
root["nostrZapPubkey"] = preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY);
root["ledFlashOnZap"] = preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP);
// 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);
root["ledTestOnPower"] = preferences.getBool("ledTestOnPower", DEFAULT_LED_TEST_ON_POWER);
root["ledFlashOnUpd"] = preferences.getBool("ledFlashOnUpd", DEFAULT_LED_FLASH_ON_UPD);
root["ledBrightness"] = preferences.getUInt("ledBrightness", DEFAULT_LED_BRIGHTNESS);
@ -645,7 +686,6 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
root["mcapBigChar"] = preferences.getBool("mcapBigChar", DEFAULT_MCAP_BIG_CHAR);
root["mdnsEnabled"] = preferences.getBool("mdnsEnabled", DEFAULT_MDNS_ENABLED);
root["otaEnabled"] = preferences.getBool("otaEnabled", DEFAULT_OTA_ENABLED);
// root["fetchEurPrice"] = preferences.getBool("fetchEurPrice", DEFAULT_FETCH_EUR_PRICE);
root["useSatsSymbol"] = preferences.getBool("useSatsSymbol", DEFAULT_USE_SATS_SYMBOL);
root["useBlkCountdown"] = preferences.getBool("useBlkCountdown", DEFAULT_USE_BLOCK_COUNTDOWN);
root["suffixPrice"] = preferences.getBool("suffixPrice", DEFAULT_SUFFIX_PRICE);
@ -660,15 +700,6 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
root["hostname"] = getMyHostname();
root["ip"] = WiFi.localIP();
root["txPower"] = WiFi.getTxPower();
root["ownDataSource"] = preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE);
root["srcV2Currency"] = preferences.getChar("srcV2Currency", DEFAULT_V2_SOURCE_CURRENCY);
root["nostrPubKey"] = preferences.getString("nostrPubKey", DEFAULT_NOSTR_NPUB);
root["nostrRelay"] = preferences.getString("nostrRelay", DEFAULT_NOSTR_RELAY);
root["nostrZapNotify"] = preferences.getBool("nostrZapNotify", DEFAULT_ZAP_NOTIFY_ENABLED);
root["nostrZapPubkey"] = preferences.getString("nostrZapPubkey", DEFAULT_ZAP_NOTIFY_PUBKEY);
root["ledFlashOnZap"] = preferences.getBool("ledFlashOnZap", DEFAULT_LED_FLASH_ON_ZAP);
root["gitReleaseUrl"] = preferences.getString("gitReleaseUrl", DEFAULT_GIT_RELEASE_URL);
@ -730,8 +761,6 @@ void onApiSettingsGet(AsyncWebServerRequest *request)
}
root["poolLogosUrl"] = preferences.getString("poolLogosUrl", DEFAULT_MINING_POOL_LOGOS_URL);
root["ceEnabled"] = preferences.getBool("ceEnabled", DEFAULT_CUSTOM_ENDPOINT_ENABLED);
root["ceEndpoint"] = preferences.getString("ceEndpoint", DEFAULT_CUSTOM_ENDPOINT);
root["ceDisableSSL"] = preferences.getBool("ceDisableSSL", DEFAULT_CUSTOM_ENDPOINT_DISABLE_SSL);

View file

@ -135,7 +135,7 @@ extern "C" void app_main() {
Serial.begin(115200);
setup();
bool ownDataSource = preferences.getBool("ownDataSource", DEFAULT_OWN_DATA_SOURCE);
bool thirdPartySource = getDataSource() == THIRD_PARTY_SOURCE;
while (true) {
@ -147,7 +147,7 @@ extern "C" void app_main() {
handleFrontlight();
checkWiFiConnection();
if (!ownDataSource) {
if (thirdPartySource) {
monitorDataConnections();
}