From e4a39de5fc8a91f17878cb98d65831a71ff46fee Mon Sep 17 00:00:00 2001 From: Djuri Baars Date: Wed, 31 Jan 2024 23:45:26 +0100 Subject: [PATCH] Fix lost data connection detection --- src/lib/block_notify.cpp | 12 ++++++++++++ src/lib/block_notify.hpp | 3 ++- src/lib/led_handler.cpp | 6 ++++++ src/lib/led_handler.hpp | 5 +++++ src/lib/price_notify.cpp | 11 ++++++++++- src/lib/price_notify.hpp | 3 ++- src/lib/webserver.cpp | 26 ++++++++++++++++++++++++++ src/lib/webserver.hpp | 5 ++++- src/main.cpp | 19 +++++++++++++------ 9 files changed, 80 insertions(+), 10 deletions(-) diff --git a/src/lib/block_notify.cpp b/src/lib/block_notify.cpp index 10900e8..56a2df2 100644 --- a/src/lib/block_notify.cpp +++ b/src/lib/block_notify.cpp @@ -3,6 +3,7 @@ char *wsServer; esp_websocket_client_handle_t blockNotifyClient = NULL; uint currentBlockHeight = 816000; +bool blockNotifyInit = false; // const char *mempoolWsCert = R"(-----BEGIN CERTIFICATE----- // MIIHfTCCBmWgAwIBAgIRANFX3mhqRYDt1NFuENoSyaAwDQYJKoZIhvcNAQELBQAw @@ -105,6 +106,8 @@ void onWebsocketEvent(void *handler_args, esp_event_base_t base, const String sub = "{\"action\": \"want\", \"data\":[\"blocks\"]}"; switch (event_id) { case WEBSOCKET_EVENT_CONNECTED: + blockNotifyInit = true; + Serial.println(F("Connected to Mempool.space WebSocket")); Serial.println(sub); @@ -181,7 +184,16 @@ bool isBlockNotifyConnected() { return esp_websocket_client_is_connected(blockNotifyClient); } +bool getBlockNotifyInit() { + return blockNotifyInit; +} + void stopBlockNotify() { + if (blockNotifyClient == NULL) return; + + esp_websocket_client_close(blockNotifyClient, portMAX_DELAY); esp_websocket_client_stop(blockNotifyClient); esp_websocket_client_destroy(blockNotifyClient); + + blockNotifyClient = NULL; } \ No newline at end of file diff --git a/src/lib/block_notify.hpp b/src/lib/block_notify.hpp index 3603846..f0d903d 100644 --- a/src/lib/block_notify.hpp +++ b/src/lib/block_notify.hpp @@ -24,4 +24,5 @@ void onWebsocketMessage(esp_websocket_event_data_t *event_data); void setBlockHeight(uint newBlockHeight); uint getBlockHeight(); bool isBlockNotifyConnected(); -void stopBlockNotify(); \ No newline at end of file +void stopBlockNotify(); +bool getBlockNotifyInit(); \ No newline at end of file diff --git a/src/lib/led_handler.cpp b/src/lib/led_handler.cpp index f07fbc2..56b9b69 100644 --- a/src/lib/led_handler.cpp +++ b/src/lib/led_handler.cpp @@ -32,6 +32,12 @@ void ledTask(void *parameter) { case LED_EFFECT_HEARTBEAT: blinkDelayColor(150, 2, 0, 0, 255); break; + case LED_DATA_BLOCK_ERROR: + blinkDelayColor(150, 2, 128, 0, 128); + break; + case LED_DATA_PRICE_ERROR: + blinkDelayColor(150, 2, 177, 90, 31); + break; case LED_EFFECT_WIFI_CONNECT_SUCCESS: case LED_FLASH_SUCCESS: blinkDelayColor(150, 3, 0, 255, 0); diff --git a/src/lib/led_handler.hpp b/src/lib/led_handler.hpp index c5b3780..8e064f5 100644 --- a/src/lib/led_handler.hpp +++ b/src/lib/led_handler.hpp @@ -27,10 +27,15 @@ const int LED_EFFECT_WIFI_CONNECTING = 101; const int LED_EFFECT_WIFI_CONNECT_ERROR = 102; const int LED_EFFECT_WIFI_CONNECT_SUCCESS = 103; const int LED_EFFECT_WIFI_ERASE_SETTINGS = 104; + const int LED_PROGRESS_25 = 200; const int LED_PROGRESS_50 = 201; const int LED_PROGRESS_75 = 202; const int LED_PROGRESS_100 = 203; + +const int LED_DATA_PRICE_ERROR = 300; +const int LED_DATA_BLOCK_ERROR = 301; + const int LED_POWER_TEST = 999; extern TaskHandle_t ledTaskHandle; extern Adafruit_NeoPixel pixels; diff --git a/src/lib/price_notify.cpp b/src/lib/price_notify.cpp index 00ff2a7..a380942 100644 --- a/src/lib/price_notify.cpp +++ b/src/lib/price_notify.cpp @@ -51,7 +51,6 @@ void setupPriceNotify() { esp_websocket_register_events(clientPrice, WEBSOCKET_EVENT_ANY, onWebsocketPriceEvent, clientPrice); esp_websocket_client_start(clientPrice); - priceNotifyInit = true; } void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, @@ -61,6 +60,8 @@ void onWebsocketPriceEvent(void *handler_args, esp_event_base_t base, switch (event_id) { case WEBSOCKET_EVENT_CONNECTED: Serial.println(F("Connected to CoinCap.io WebSocket")); + priceNotifyInit = true; + break; case WEBSOCKET_EVENT_DATA: onWebsocketPriceMessage(data); @@ -113,7 +114,15 @@ bool isPriceNotifyConnected() { return esp_websocket_client_is_connected(clientPrice); } +bool getPriceNotifyInit() { + return priceNotifyInit; +} + void stopPriceNotify() { + if (clientPrice == NULL) return; + esp_websocket_client_close(clientPrice, portMAX_DELAY); esp_websocket_client_stop(clientPrice); esp_websocket_client_destroy(clientPrice); + + clientPrice = NULL; } \ No newline at end of file diff --git a/src/lib/price_notify.hpp b/src/lib/price_notify.hpp index d320b2a..8bcb207 100644 --- a/src/lib/price_notify.hpp +++ b/src/lib/price_notify.hpp @@ -18,4 +18,5 @@ uint getPrice(); void setPrice(uint newPrice); bool isPriceNotifyConnected(); -void stopPriceNotify(); \ No newline at end of file +void stopPriceNotify(); +bool getPriceNotifyInit(); \ No newline at end of file diff --git a/src/lib/webserver.cpp b/src/lib/webserver.cpp index 8bb1a73..bc57f06 100644 --- a/src/lib/webserver.cpp +++ b/src/lib/webserver.cpp @@ -24,6 +24,10 @@ void setupWebserver() { server.on("/api/full_refresh", HTTP_GET, onApiFullRefresh); + server.on("/api/stop_datasources", HTTP_GET, onApiStopDataSources); + server.on("/api/restart_datasources", HTTP_GET, onApiRestartDataSources); + + server.on("/api/action/pause", HTTP_GET, onApiActionPause); server.on("/api/action/timer_restart", HTTP_GET, onApiActionTimerRestart); @@ -694,6 +698,28 @@ void onApiLightsStatus(AsyncWebServerRequest *request) { request->send(response); } +void onApiStopDataSources(AsyncWebServerRequest *request) { + AsyncResponseStream *response = + request->beginResponseStream("application/json"); + + stopPriceNotify(); + stopBlockNotify(); + + request->send(response); +} + +void onApiRestartDataSources(AsyncWebServerRequest *request) { + AsyncResponseStream *response = + request->beginResponseStream("application/json"); + + stopPriceNotify(); + stopBlockNotify(); + setupPriceNotify(); + setupBlockNotify(); + + request->send(response); +} + void onApiLightsOff(AsyncWebServerRequest *request) { setLights(0, 0, 0); request->send(200); diff --git a/src/lib/webserver.hpp b/src/lib/webserver.hpp index f9dc01f..f8afa98 100644 --- a/src/lib/webserver.hpp +++ b/src/lib/webserver.hpp @@ -49,4 +49,7 @@ void onNotFound(AsyncWebServerRequest *request); StaticJsonDocument<512> getLedStatusObject(); StaticJsonDocument<768> getStatusObject(); void eventSourceUpdate(); -void eventSourceTask(void *pvParameters); \ No newline at end of file +void eventSourceTask(void *pvParameters); + +void onApiStopDataSources(AsyncWebServerRequest *request); +void onApiRestartDataSources(AsyncWebServerRequest *request); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index de96dc8..012bf5f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,20 +55,27 @@ extern "C" void app_main() { } else if (wifiLostConnection) { wifiLostConnection = 0; Serial.println("Connection restored, reset timer."); - } else if (preferences.getBool("fetchEurPrice", false) && !isPriceNotifyConnected()) { + } else if (getPriceNotifyInit() && !preferences.getBool("fetchEurPrice", false) && !isPriceNotifyConnected()) { priceNotifyLostConnection++; + Serial.println("Lost price data connection..."); + queueLedEffect(LED_DATA_PRICE_ERROR); + + // if price WS connection does not come back after 6*5 seconds, destroy and recreate + if (priceNotifyLostConnection > 6) { + Serial.println("Restarting price handler..."); - // if price WS connection does not come back after 60 seconds, destroy and recreate - if (priceNotifyLostConnection > 12) { stopPriceNotify(); setupPriceNotify(); priceNotifyLostConnection = 0; } - } else if (!isBlockNotifyConnected()) { + } else if (getBlockNotifyInit() && !isBlockNotifyConnected()) { blockNotifyLostConnection++; + Serial.println("Lost block data connection..."); + queueLedEffect(LED_DATA_BLOCK_ERROR); + // if mempool WS connection does not come back after 6*5 seconds, destroy and recreate + if (blockNotifyLostConnection > 6) { + Serial.println("Restarting block handler..."); - // if mempool WS connection does not come back after 60 seconds, destroy and recreate - if (blockNotifyLostConnection > 12) { stopBlockNotify(); setupBlockNotify(); blockNotifyLostConnection = 0;