From f58d779b2ba53a238387bf80e678403ab7aa21e2 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Tue, 2 Feb 2021 14:57:53 +0100
Subject: [PATCH] Add optional SSE demo
---
.../HTTP_SCRIPT_ROOT_SSE_NO_WEB_DISPLAY.h | 21 ++++++++++++
tasmota/xdrv_01_webserver.ino | 32 +++++++++++++------
tasmota/xdrv_10_scripter.ino | 4 +--
tasmota/xdrv_20_hue.ino | 12 +++----
tasmota/xdrv_23_zigbee_3_hue.ino | 2 +-
tasmota/xdrv_50_filesystem.ino | 4 +--
tasmota/xsns_60_GPS.ino | 2 +-
7 files changed, 56 insertions(+), 21 deletions(-)
create mode 100644 tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_SSE_NO_WEB_DISPLAY.h
diff --git a/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_SSE_NO_WEB_DISPLAY.h b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_SSE_NO_WEB_DISPLAY.h
new file mode 100644
index 000000000..bc2c28745
--- /dev/null
+++ b/tasmota/html_uncompressed/HTTP_SCRIPT_ROOT_SSE_NO_WEB_DISPLAY.h
@@ -0,0 +1,21 @@
+const char HTTP_SCRIPT_ROOT[] PROGMEM =
+ "function la(p){"
+ "if(typeof(EventSource)!==\"undefined\"){"
+ "var e=new EventSource('?m=1');"
+ "e.onmessage=function(event){"
+ "eb('l1').innerHTML=event.data.replace(/{t}/g,\"
\")"
+ ".replace(/{s}/g,\"\")"
+ // ".replace(/{m}/g,\" | \")"
+ ".replace(/{m}/g,\" | \")" // I want a right justified column with left justified text
+ ".replace(/{e}/g,\" |
\")"
+ ".replace(/{c}/g,\"%%'>hasArg("m")
+ "x.send();"
+ "lt=setTimeout(la,20000);" // 20s failure timeout
+ "}";
diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino
index 2598a295d..98357fe52 100644
--- a/tasmota/xdrv_01_webserver.ino
+++ b/tasmota/xdrv_01_webserver.ino
@@ -27,6 +27,9 @@
#define XDRV_01 1
+// Enable below demo feature only if defines USE_UNISHOX_COMPRESSION and USE_SCRIPT_WEB_DISPLAY are disabled
+//#define USE_WEB_SSE
+
#ifndef WIFI_SOFT_AP_CHANNEL
#define WIFI_SOFT_AP_CHANNEL 1 // Soft Access Point Channel number between 1 and 11 as used by WifiManager web GUI
#endif
@@ -61,8 +64,6 @@ enum UploadTypes { UPL_TASMOTA, UPL_SETTINGS, UPL_EFM8BB1, UPL_TASMOTACLIENT, UP
#endif
#endif
-
-
const char HTTP_SCRIPT_COUNTER[] PROGMEM =
"var cn=180;" // seconds
"function u(){"
@@ -74,7 +75,6 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM =
"}"
"wl(u);";
-
#ifdef USE_UNISHOX_COMPRESSION
#ifdef USE_SCRIPT_WEB_DISPLAY
#include "./html_compressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h"
@@ -86,7 +86,11 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM =
#ifdef USE_SCRIPT_WEB_DISPLAY
#include "./html_uncompressed/HTTP_SCRIPT_ROOT_WEB_DISPLAY.h"
#else
- #include "./html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h"
+ #ifdef USE_WEB_SSE
+ #include "./html_uncompressed/HTTP_SCRIPT_ROOT_SSE_NO_WEB_DISPLAY.h"
+ #else
+ #include "./html_uncompressed/HTTP_SCRIPT_ROOT_NO_WEB_DISPLAY.h"
+ #endif // USE_WEB_SSE
#endif
#include "./html_uncompressed/HTTP_SCRIPT_ROOT_PART2.h"
#endif
@@ -346,8 +350,8 @@ const char kButtonAction[] PROGMEM =
"md|wi|lg|co|tp|dl|rs";
const char kButtonConfirm[] PROGMEM = D_CONFIRM_RESTART "|" D_CONFIRM_RESET_CONFIGURATION;
-enum CTypes { CT_HTML, CT_PLAIN, CT_XML, CT_JSON, CT_STREAM };
-const char kContentTypes[] PROGMEM = "text/html|text/plain|text/xml|application/json|application/octet-stream";
+enum CTypes { CT_HTML, CT_PLAIN, CT_XML, CT_STREAM, CT_APP_JSON, CT_APP_STREAM };
+const char kContentTypes[] PROGMEM = "text/html|text/plain|text/xml|text/event-stream|application/json|application/octet-stream";
const char kLoggingOptions[] PROGMEM = D_SERIAL_LOG_LEVEL "|" D_WEB_LOG_LEVEL "|" D_MQTT_LOG_LEVEL "|" D_SYS_LOG_LEVEL;
const char kLoggingLevels[] PROGMEM = D_NONE "|" D_ERROR "|" D_INFO "|" D_DEBUG "|" D_MORE_DEBUG;
@@ -1223,7 +1227,13 @@ bool HandleRootStatusRefresh(void)
ExecuteWebCommand(svalue, SRC_WEBGUI);
}
#endif // USE_ZIGBEE
+
+#ifdef USE_WEB_SSE
+ WSContentBegin(200, CT_STREAM);
+ WSContentSend_P(PSTR("data: "));
+#else
WSContentBegin(200, CT_HTML);
+#endif // USE_WEB_SSE
WSContentSend_P(PSTR("{t}"));
XsnsCall(FUNC_WEB_SENSOR);
XdrvCall(FUNC_WEB_SENSOR);
@@ -1259,6 +1269,10 @@ bool HandleRootStatusRefresh(void)
}
}
#endif // USE_TUYA_MCU
+
+#ifdef USE_WEB_SSE
+ WSContentSend_P(PSTR("\n\n"));
+#endif // USE_WEB_SSE
WSContentEnd();
return true;
@@ -1990,7 +2004,7 @@ void HandleBackupConfiguration(void)
Webserver->sendHeader(F("Content-Disposition"), attachment);
- WSSend(200, CT_STREAM, "");
+ WSSend(200, CT_APP_STREAM, "");
uint32_t cfg_crc32 = Settings.cfg_crc32;
Settings.cfg_crc32 = GetSettingsCrc32(); // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
@@ -2671,14 +2685,14 @@ void HandleHttpCommand(void)
WebGetArg(PSTR("password"), tmp2, sizeof(tmp2));
if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) {
- WSContentBegin(401, CT_JSON);
+ WSContentBegin(401, CT_APP_JSON);
WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}"));
WSContentEnd();
return;
}
}
- WSContentBegin(200, CT_JSON);
+ WSContentBegin(200, CT_APP_JSON);
String svalue = Webserver->arg(F("cmnd"));
if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) {
uint32_t curridx = TasmotaGlobal.log_buffer_pointer;
diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino
index c42d8163c..9dd314b71 100755
--- a/tasmota/xdrv_10_scripter.ino
+++ b/tasmota/xdrv_10_scripter.ino
@@ -4926,7 +4926,7 @@ uint8_t DownloadFile(char *file) {
}
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"), cp);
Webserver->sendHeader(F("Content-Disposition"), attachment);
- WSSend(200, CT_STREAM, "");
+ WSSend(200, CT_APP_STREAM, "");
uint8_t buff[512];
uint16_t bread;
@@ -5599,7 +5599,7 @@ void Script_Handle_Hue(String *path) {
response = FPSTR(sHUE_ERROR_JSON);
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str());
- WSSend(code, CT_JSON, response);
+ WSSend(code, CT_APP_JSON, response);
if (resp) {
Run_Scripter(">E", 2, 0);
}
diff --git a/tasmota/xdrv_20_hue.ino b/tasmota/xdrv_20_hue.ino
index 4e677157d..475e61702 100644
--- a/tasmota/xdrv_20_hue.ino
+++ b/tasmota/xdrv_20_hue.ino
@@ -438,7 +438,7 @@ void HueNotImplemented(String *path)
{
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE_API_NOT_IMPLEMENTED " (%s)"), path->c_str());
- WSSend(200, CT_JSON, PSTR("{}"));
+ WSSend(200, CT_APP_JSON, PSTR("{}"));
}
void HueConfigResponse(String *response)
@@ -457,7 +457,7 @@ void HueConfig(String *path)
{
String response = "";
HueConfigResponse(&response);
- WSSend(200, CT_JSON, response);
+ WSSend(200, CT_APP_JSON, response);
}
// device is forced to CT mode instead of HSB
@@ -680,7 +680,7 @@ void HueGlobalConfig(String *path) {
response += F("},\"groups\":{},\"schedules\":{},\"config\":");
HueConfigResponse(&response);
response += F("}");
- WSSend(200, CT_JSON, response);
+ WSSend(200, CT_APP_JSON, response);
}
void HueAuthentication(String *path)
@@ -688,7 +688,7 @@ void HueAuthentication(String *path)
char response[38];
snprintf_P(response, sizeof(response), PSTR("[{\"success\":{\"username\":\"%s\"}}]"), GetHueUserId().c_str());
- WSSend(200, CT_JSON, response);
+ WSSend(200, CT_APP_JSON, response);
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Authentication Result (%s)"), response);
}
@@ -996,7 +996,7 @@ void HueLights(String *path)
}
exit:
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str());
- WSSend(code, CT_JSON, response);
+ WSSend(code, CT_APP_JSON, response);
}
void HueGroups(String *path)
@@ -1029,7 +1029,7 @@ void HueGroups(String *path)
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " HueGroups Result (%s)"), path->c_str());
- WSSend(200, CT_JSON, response);
+ WSSend(200, CT_APP_JSON, response);
}
void HandleHueApi(String *path)
diff --git a/tasmota/xdrv_23_zigbee_3_hue.ino b/tasmota/xdrv_23_zigbee_3_hue.ino
index e2a060ef8..7fa7d657b 100644
--- a/tasmota/xdrv_23_zigbee_3_hue.ino
+++ b/tasmota/xdrv_23_zigbee_3_hue.ino
@@ -384,7 +384,7 @@ void ZigbeeHandleHue(uint16_t shortaddr, uint32_t device_id, String &response) {
response = msg[HUE_ERROR_JSON];
}
AddLog_P(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_HTTP D_HUE " Result (%s)"), response.c_str());
- WSSend(code, CT_JSON, response);
+ WSSend(code, CT_APP_JSON, response);
free(buf);
}
diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino
index aacdf543d..c5accd4a7 100644
--- a/tasmota/xdrv_50_filesystem.ino
+++ b/tasmota/xdrv_50_filesystem.ino
@@ -625,7 +625,7 @@ uint8_t UfsDownloadFile(char *file) {
}
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"), cp);
Webserver->sendHeader(F("Content-Disposition"), attachment);
- WSSend(200, CT_STREAM, "");
+ WSSend(200, CT_APP_STREAM, "");
uint8_t buff[512];
uint32_t bread;
@@ -696,7 +696,7 @@ void donload_task(void *path) {
}
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=%s"), cp);
Webserver->sendHeader(F("Content-Disposition"), attachment);
- WSSend(200, CT_STREAM, "");
+ WSSend(200, CT_APP_STREAM, "");
uint8_t *buff = (uint8_t*)malloc(DOWNLOAD_SIZE);
if (buff) {
diff --git a/tasmota/xsns_60_GPS.ino b/tasmota/xsns_60_GPS.ino
index 56c6f4f10..7a760bd14 100644
--- a/tasmota/xsns_60_GPS.ino
+++ b/tasmota/xsns_60_GPS.ino
@@ -490,7 +490,7 @@ void UBXsendHeader(void)
{
Webserver->setContentLength(CONTENT_LENGTH_UNKNOWN);
Webserver->sendHeader(F("Content-Disposition"), F("attachment; filename=TASMOTA.gpx"));
- WSSend(200, CT_STREAM, F(
+ WSSend(200, CT_APP_STREAM, F(
"\r\n"
"