diff --git a/CHANGELOG.md b/CHANGELOG.md index 90c881e1d..67615e03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Scripter memory leak in `>w x` (#20473) - ESP8266 GPIO Viewer exception 9 on reading Analog GPIO +- GPIO Viewer single instance ### Removed diff --git a/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino b/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino index 7d558cc45..2685acfe9 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_121_gpioviewer.ino @@ -105,6 +105,15 @@ struct { bool sse_ready; } GV; +void GVStop(void) { + GV.sse_ready = false; + GV.ticker.detach(); + GV.active = false; + + GV.WebServer->stop(); + GV.WebServer = nullptr; +} + void GVBegin(void) { if (0 == GV.sampling) { GV.sampling = (GV_SAMPLING_INTERVAL < 20) ? 20 : GV_SAMPLING_INTERVAL; @@ -115,40 +124,18 @@ void GVBegin(void) { GV.WebServer->sendHeader("Access-Control-Allow-Origin", "*"); GV.WebServer->sendHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); GV.WebServer->sendHeader("Access-Control-Allow-Headers", "Content-Type"); - GV.WebServer->on("/events", GVHandleEvents); GV.WebServer->on("/", GVHandleRoot); GV.WebServer->on("/release", GVHandleRelease); GV.WebServer->on("/free_psram", GVHandleFreePSRam); + GV.WebServer->on("/events", GVHandleEvents); GV.WebServer->begin(); GV.active = true; } -void GVStop(void) { - GV.sse_ready = false; - GV.ticker.detach(); - GV.active = false; - - GV.WebServer->stop(); - GV.WebServer = nullptr; -} - -void GVHandleEvents(void) { - GV.WebClient = GV.WebServer->client(); - GV.WebClient.setNoDelay(true); -// GV.WebClient.setSync(true); - - GV.WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); // The payload can go on forever - GV.WebServer->sendContent_P(HTTP_GV_EVENT); - - GV.sse_ready = true; // Ready for async updates - if (GV.sampling != 100) { - GV.ticker.attach_ms(GV.sampling, GVMonitorTask); // Use Tasmota Scheduler (100) or Ticker (20..99,101..1000) - } - AddLog(LOG_LEVEL_DEBUG, PSTR("IOV: Connected")); -} - void GVHandleRoot(void) { + GVCloseEvent(); + char* content = ext_snprintf_malloc_P(HTTP_GV_PAGE, SettingsTextEscaped(SET_DEVICENAME).c_str(), WiFi.localIP().toString().c_str(), @@ -161,9 +148,6 @@ void GVHandleRoot(void) { if (content == nullptr) { return; } // Avoid crash GV.WebServer->send_P(200, "text/html", content); free(content); - - GV.sse_ready = false; // Allow restart of updates on page load - GV.ticker.detach(); } void GVHandleRelease(void) { @@ -182,6 +166,34 @@ void GVHandleFreePSRam(void) { GV.WebServer->send(200, "application/json", jsonResponse); } +void GVHandleEvents(void) { + GV.WebClient = GV.WebServer->client(); + GV.WebClient.setNoDelay(true); +// GV.WebClient.setSync(true); + + GV.WebServer->setContentLength(CONTENT_LENGTH_UNKNOWN); // The payload can go on forever + GV.WebServer->sendContent_P(HTTP_GV_EVENT); + + GV.sse_ready = true; // Ready for async updates + if (GV.sampling != 100) { + GV.ticker.attach_ms(GV.sampling, GVMonitorTask); // Use Tasmota Scheduler (100) or Ticker (20..99,101..1000) + } + AddLog(LOG_LEVEL_DEBUG, PSTR("IOV: Connected")); +} + +void GVEventDisconnected(void) { + if (GV.sse_ready) { + AddLog(LOG_LEVEL_D