From 5d0ea57e2391b272a114eec25266f7bd859a7986 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 20 Dec 2020 12:46:57 +0100 Subject: [PATCH 01/12] [Cleanup] Exclude unused code to reduce build size --- src/ESPEasy.ino | 2 ++ src/src/DataStructs/GpioFactorySettingsStruct.cpp | 6 ++++++ src/src/ESPEasyCore/ESPEasyRules.cpp | 4 ++-- src/src/ESPEasyCore/ESPEasyWifi.cpp | 2 ++ src/src/Helpers/Hardware.cpp | 11 ++++++++++- src/src/Helpers/Scheduler.cpp | 2 ++ src/src/Helpers/_Plugin_Helper_serial.cpp | 6 ++++++ src/src/Helpers/_Plugin_Helper_serial.h | 2 ++ 8 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/ESPEasy.ino b/src/ESPEasy.ino index b59fc81aa6..aaa5abc38d 100644 --- a/src/ESPEasy.ino +++ b/src/ESPEasy.ino @@ -276,10 +276,12 @@ void setup() } log += RTC.bootCounter; + #ifndef BUILD_NO_DEBUG log += F(" Last Action before Reboot: "); log += ESPEasy_Scheduler::decodeSchedulerId(lastMixedSchedulerId_beforereboot); log += F(" Last systime: "); log += RTC.lastSysTime; + #endif } //cold boot (RTC memory empty) else diff --git a/src/src/DataStructs/GpioFactorySettingsStruct.cpp b/src/src/DataStructs/GpioFactorySettingsStruct.cpp index 46927501b0..25c37540c2 100644 --- a/src/src/DataStructs/GpioFactorySettingsStruct.cpp +++ b/src/src/DataStructs/GpioFactorySettingsStruct.cpp @@ -88,6 +88,7 @@ GpioFactorySettingsStruct::GpioFactorySettingsStruct(DeviceModel model) i2c_sda = -1; // GPIO4 conflicts with relay control. i2c_scl = -1; // GPIO5 conflicts with SW input break; +#ifdef ESP32 case DeviceMode_Olimex_ESP32_PoE: button[0] = 34; // BUT1 Button relais[0] = -1; // No LED's or relays on board @@ -152,6 +153,11 @@ GpioFactorySettingsStruct::GpioFactorySettingsStruct(DeviceModel model) // N.B. GPIO 35 and up are input only. break; + #else + case DeviceMode_Olimex_ESP32_PoE: + case DeviceMode_Olimex_ESP32_EVB: + case DeviceMode_Olimex_ESP32_GATEWAY: + #endif case DeviceModel_default: case DeviceModel_MAX: diff --git a/src/src/ESPEasyCore/ESPEasyRules.cpp b/src/src/ESPEasyCore/ESPEasyRules.cpp index 1b822a4591..88318d8862 100644 --- a/src/src/ESPEasyCore/ESPEasyRules.cpp +++ b/src/src/ESPEasyCore/ESPEasyRules.cpp @@ -188,7 +188,7 @@ String rulesProcessingFile(const String& fileName, String& event) { #endif // ifndef BUILD_NO_DEBUG static byte nestingLevel = 0; - String log = ""; + String log; nestingLevel++; @@ -584,7 +584,7 @@ void parseCompleteNonCommentLine(String& line, String& event, String& log, String lineOrg = line; // store original line for future use line.toLowerCase(); // convert all to lower case to make checks easier - String eventTrigger = ""; + String eventTrigger; action = ""; if (!codeBlock) // do not check "on" rules if a block of actions is to be diff --git a/src/src/ESPEasyCore/ESPEasyWifi.cpp b/src/src/ESPEasyCore/ESPEasyWifi.cpp index 6ecc0a8204..7e9657f351 100644 --- a/src/src/ESPEasyCore/ESPEasyWifi.cpp +++ b/src/src/ESPEasyCore/ESPEasyWifi.cpp @@ -914,6 +914,7 @@ String getLastDisconnectReason() { reason += WiFiEventData.lastDisconnectReason; reason += F(") "); + #ifndef LIMIT_BUILD_SIZE switch (WiFiEventData.lastDisconnectReason) { case WIFI_DISCONNECT_REASON_UNSPECIFIED: reason += F("Unspecified"); break; case WIFI_DISCONNECT_REASON_AUTH_EXPIRE: reason += F("Auth expire"); break; @@ -945,5 +946,6 @@ String getLastDisconnectReason() { case WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT: reason += F("Handshake timeout"); break; default: reason += getUnknownString(); break; } + #endif return reason; } diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index de6d6240b1..4a3b66a54b 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -533,7 +533,10 @@ String getDeviceModelBrandString(DeviceModel model) { case DeviceModel_ShellyPLUG_S: return F("Shelly"); case DeviceMode_Olimex_ESP32_PoE: case DeviceMode_Olimex_ESP32_EVB: - case DeviceMode_Olimex_ESP32_GATEWAY: return F("Olimex"); + case DeviceMode_Olimex_ESP32_GATEWAY: + #ifdef ESP32 + return F("Olimex"); + #endif case DeviceModel_default: case DeviceModel_MAX: break; @@ -561,9 +564,15 @@ String getDeviceModelString(DeviceModel model) { case DeviceModel_Sonoff_POWr2: result += F(" POW-r2"); break; case DeviceModel_Shelly1: result += '1'; break; case DeviceModel_ShellyPLUG_S: result += F(" PLUG S"); break; + #ifdef ESP32 case DeviceMode_Olimex_ESP32_PoE: result += F(" ESP32-PoE"); break; case DeviceMode_Olimex_ESP32_EVB: result += F(" ESP32-EVB"); break; case DeviceMode_Olimex_ESP32_GATEWAY: result += F(" ESP32-GATEWAY"); break; + #else + case DeviceMode_Olimex_ESP32_PoE: + case DeviceMode_Olimex_ESP32_EVB: + case DeviceMode_Olimex_ESP32_GATEWAY: + #endif case DeviceModel_default: case DeviceModel_MAX: result += F("default"); break; diff --git a/src/src/Helpers/Scheduler.cpp b/src/src/Helpers/Scheduler.cpp index e30fe7201e..16caa16b73 100644 --- a/src/src/Helpers/Scheduler.cpp +++ b/src/src/Helpers/Scheduler.cpp @@ -132,6 +132,7 @@ String ESPEasy_Scheduler::decodeSchedulerId(unsigned long mixed_id) { const unsigned long id = decodeSchedulerId(mixed_id, timerType); String idStr = String(id); String result = String(timerType); +#ifndef BUILD_NO_DEBUG result.reserve(64); switch (timerType) { case CONST_INTERVAL_TIMER: @@ -208,6 +209,7 @@ String ESPEasy_Scheduler::decodeSchedulerId(unsigned long mixed_id) { return result; } } +#endif result += F(" timer, id: "); result += idStr; return result; diff --git a/src/src/Helpers/_Plugin_Helper_serial.cpp b/src/src/Helpers/_Plugin_Helper_serial.cpp index a8e9f0b7a6..d96e43ebc2 100644 --- a/src/src/Helpers/_Plugin_Helper_serial.cpp +++ b/src/src/Helpers/_Plugin_Helper_serial.cpp @@ -102,6 +102,7 @@ String serialHelper_getSerialTypeLabel(struct EventStruct *event) { return serialHelper_getSerialTypeLabel(serialHelper_getSerialType(event)); } +#ifndef DISABLE_SC16IS752_Serial void serialHelper_addI2CuartSelectors(int address, int channel) { #define SC16IS752_I2C_ADDRESSES 16 #define SC16IS752_I2C_BASE_ADDR (0x90 >> 1) @@ -144,6 +145,7 @@ void serialHelper_addI2CuartSelectors(int address, int channel) { addFormSelector(F("Channel"), F("i2cuart_ch"), SC16IS752_CHANNELS, chOptions, chValues, channel); } } +#endif void serialHelper_webformLoad(struct EventStruct *event) { serialHelper_webformLoad(event, true); @@ -162,7 +164,9 @@ void serialHelper_webformLoad(struct EventStruct *event, bool allowSoftwareSeria void serialHelper_webformLoad(ESPEasySerialPort port, int rxPinDef, int txPinDef, bool allowSoftwareSerial) { // Field for I2C addr & RX are shared // Field for channel and TX are shared + #ifndef DISABLE_SC16IS752_Serial serialHelper_addI2CuartSelectors(rxPinDef, txPinDef); + #endif #ifdef ESP8266 // Script to show GPIO pins for SoftwareSerial or I2C addresses for the I2C to UART bridge @@ -262,10 +266,12 @@ void serialHelper_webformSave(byte& port, int8_t& rxPin, int8_t& txPin) { switch (serType) { case ESPEasySerialPort::software: break; + #ifndef DISABLE_SC16IS752_Serial case ESPEasySerialPort::sc16is752: rxPin = getFormItemInt(F("i2cuart_addr"), rxPin); txPin = getFormItemInt(F("i2cuart_ch"), txPin); break; + #endif case ESPEasySerialPort::serial0: case ESPEasySerialPort::serial0_swap: case ESPEasySerialPort::serial1: diff --git a/src/src/Helpers/_Plugin_Helper_serial.h b/src/src/Helpers/_Plugin_Helper_serial.h index 7fd46804d9..1f85470f10 100644 --- a/src/src/Helpers/_Plugin_Helper_serial.h +++ b/src/src/Helpers/_Plugin_Helper_serial.h @@ -24,7 +24,9 @@ ESPEasySerialPort serialHelper_getSerialType(struct EventStruct *event); String serialHelper_getSerialTypeLabel(struct EventStruct *event); +#ifndef DISABLE_SC16IS752_Serial void serialHelper_addI2CuartSelectors(int address, int channel); +#endif void serialHelper_webformLoad(struct EventStruct *event); From acd4219eb7f4a6d947db819ca0fe30aa21dce203 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 21 Dec 2020 02:31:34 +0100 Subject: [PATCH 02/12] [Cleanup] Reduce build size by using CDN for CSS and JS --- src/src/CustomBuild/define_plugin_sets.h | 36 +- src/src/DataStructs/Caches.cpp | 5 +- src/src/DataStructs/Caches.h | 8 +- src/src/Helpers/ESPEasy_Storage.cpp | 20 +- src/src/Helpers/StringConverter.cpp | 2 + src/src/Helpers/WebServer_commandHelper.cpp | 22 +- src/src/Helpers/_CPlugin_DomoticzHelper.cpp | 32 +- src/src/Static/WebStaticData.cpp | 121 +++ src/src/Static/WebStaticData.h | 32 +- src/src/WebServer/DevicesPage.cpp | 24 +- src/src/WebServer/LoadFromFS.cpp | 3 + src/src/WebServer/Log.cpp | 4 +- src/src/WebServer/RootPage.cpp | 6 +- src/src/WebServer/Rules.cpp | 4 +- src/src/WebServer/SysInfoPage.cpp | 8 +- src/src/WebServer/UploadPage.cpp | 42 +- src/src/WebServer/UploadPage.h | 11 +- src/src/WebServer/WebServer.cpp | 32 +- static/espeasy_default.css | 969 +++++++++++--------- static/fetch_and_parse_log.js | 3 +- static/reboot.js | 38 +- static/rules_save.js | 68 +- static/toasting,js | 9 + 23 files changed, 921 insertions(+), 578 deletions(-) create mode 100644 src/src/Static/WebStaticData.cpp create mode 100644 static/toasting,js diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index b03d2a3ff7..a0669a5279 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -45,6 +45,12 @@ To create/register a plugin, you have to : #ifndef WEBSERVER_FAVICON #define WEBSERVER_FAVICON #endif + #ifndef WEBSERVER_CSS + #define WEBSERVER_CSS + #endif + #ifndef WEBSERVER_INCLUDE_JS + #define WEBSERVER_INCLUDE_JS + #endif #ifndef WEBSERVER_LOG #define WEBSERVER_LOG #endif @@ -323,6 +329,12 @@ To create/register a plugin, you have to : #ifdef WEBSERVER_FAVICON #undef WEBSERVER_FAVICON #endif + #ifdef WEBSERVER_CSS + #undef WEBSERVER_CSS + #endif + #ifdef WEBSERVER_INCLUDE_JS + #undef WEBSERVER_INCLUDE_JS + #endif #ifdef WEBSERVER_LOG #undef WEBSERVER_LOG #endif @@ -1037,7 +1049,10 @@ To create/register a plugin, you have to : /******************************************************************************\ * Libraries dependencies ***************************************************** \******************************************************************************/ -#if defined(USES_P049) || defined(USES_P052) || defined(USES_P053) || defined(USES_P056) || defined(USES_P071) || defined(USES_P075) || defined(USES_P082) || defined(USES_P087) || defined(USES_P094) +#if defined(USES_P049) || defined(USES_P052) || defined(USES_P053) || defined(USES_P056) || defined(USES_P071) || defined(USES_P075) || defined(USES_P078) || defined(USES_P082) || defined(USES_P085) || defined(USES_P087) || defined(USES_P094) || defined(USES_P102) + #ifndef PLUGIN_USES_SERIAL + #define PLUGIN_USES_SERIAL + #endif // At least one plugin uses serial. #else // No plugin uses serial, so make sure software serial is not included. @@ -1113,6 +1128,11 @@ To create/register a plugin, you have to : #undef WEBSERVER_TIMINGSTATS #endif + // Do not include large blobs but fetch them from CDN + #ifndef WEBSERVER_USE_CDN_JS_CSS + #define WEBSERVER_USE_CDN_JS_CSS + #endif + #ifndef BUILD_NO_DEBUG #define BUILD_NO_DEBUG #endif @@ -1179,7 +1199,21 @@ To create/register a plugin, you have to : #ifndef BUILD_NO_RAM_TRACKER #define BUILD_NO_RAM_TRACKER #endif +#endif + // Do not include large blobs but fetch them from CDN +#ifdef WEBSERVER_USE_CDN_JS_CSS + #ifdef WEBSERVER_FAVICON + #ifndef WEBSERVER_FAVICON_CDN + #define WEBSERVER_FAVICON_CDN + #endif + #endif + #ifdef WEBSERVER_CSS + #undef WEBSERVER_CSS + #endif + #ifdef WEBSERVER_INCLUDE_JS + #undef WEBSERVER_INCLUDE_JS + #endif #endif #if defined(USES_C002) || defined (USES_C005) || defined(USES_C006) || defined(USES_C014) || defined(USES_P037) diff --git a/src/src/DataStructs/Caches.cpp b/src/src/DataStructs/Caches.cpp index 02bc9bc29d..448eb79fdc 100644 --- a/src/src/DataStructs/Caches.cpp +++ b/src/src/DataStructs/Caches.cpp @@ -4,6 +4,5 @@ void Caches::clearAllCaches() { taskIndexName.clear(); taskIndexValueName.clear(); - - -} \ No newline at end of file + fileExistsMap.clear(); +} diff --git a/src/src/DataStructs/Caches.h b/src/src/DataStructs/Caches.h index bf40afc53b..4f389725fc 100644 --- a/src/src/DataStructs/Caches.h +++ b/src/src/DataStructs/Caches.h @@ -5,15 +5,17 @@ #include "../../ESPEasy_common.h" #include "../Globals/Plugins.h" -typedef std::map TaskIndexNameMap; -typedef std::map TaskIndexValueNameMap; +typedef std::mapTaskIndexNameMap; +typedef std::map TaskIndexValueNameMap; +typedef std::map FilePresenceMap; struct Caches { void clearAllCaches(); - TaskIndexNameMap taskIndexName; + TaskIndexNameMap taskIndexName; TaskIndexValueNameMap taskIndexValueName; + FilePresenceMap fileExistsMap; }; diff --git a/src/src/Helpers/ESPEasy_Storage.cpp b/src/src/Helpers/ESPEasy_Storage.cpp index 5d2eda6e70..81337fe58c 100644 --- a/src/src/Helpers/ESPEasy_Storage.cpp +++ b/src/src/Helpers/ESPEasy_Storage.cpp @@ -117,7 +117,14 @@ String appendToFile(const String& fname, const uint8_t *data, unsigned int size) } bool fileExists(const String& fname) { - return ESPEASY_FS.exists(patch_fname(fname)); + const String patched_fname = patch_fname(fname); + auto search = Cache.fileExistsMap.find(patched_fname); + if (search != Cache.fileExistsMap.end()) { + return search->second; + } + bool res = ESPEASY_FS.exists(patched_fname); + Cache.fileExistsMap[patched_fname] = res; + return res; } fs::File tryOpenFile(const String& fname, const String& mode) { @@ -129,8 +136,11 @@ fs::File tryOpenFile(const String& fname, const String& mode) { bool exists = fileExists(fname); - if ((mode == F("r")) && !exists) { - return f; + if (!exists) { + if (mode == F("r")) { + return f; + } + Cache.fileExistsMap.clear(); } f = ESPEASY_FS.open(patch_fname(fname), mode.c_str()); STOP_TIMER(TRY_OPEN_FILE); @@ -138,7 +148,9 @@ fs::File tryOpenFile(const String& fname, const String& mode) { } bool tryRenameFile(const String& fname_old, const String& fname_new) { + Cache.fileExistsMap.clear(); if (fileExists(fname_old) && !fileExists(fname_new)) { + clearAllCaches(); return ESPEASY_FS.rename(patch_fname(fname_old), patch_fname(fname_new)); } return false; @@ -148,6 +160,7 @@ bool tryDeleteFile(const String& fname) { if (fname.length() > 0) { bool res = ESPEASY_FS.remove(patch_fname(fname)); + clearAllCaches(); // A call to GarbageCollection() will at most erase a single block. (e.g. 8k block size) // A deleted file may have covered more than a single block, so try to clear multiple blocks. @@ -277,6 +290,7 @@ void fileSystemCheck() if (ESPEASY_FS.begin()) { + clearAllCaches(); #if defined(ESP8266) fs::FSInfo fs_info; ESPEASY_FS.info(fs_info); diff --git a/src/src/Helpers/StringConverter.cpp b/src/src/Helpers/StringConverter.cpp index 93573c9715..4d02411c13 100644 --- a/src/src/Helpers/StringConverter.cpp +++ b/src/src/Helpers/StringConverter.cpp @@ -218,6 +218,7 @@ String doFormatUserVar(struct EventStruct *event, byte rel_index, bool mustCheck if (valueCount <= rel_index) { isvalid = false; + #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_ERROR)) { String log = F("No sensor value for TaskIndex: "); log += event->TaskIndex + 1; @@ -227,6 +228,7 @@ String doFormatUserVar(struct EventStruct *event, byte rel_index, bool mustCheck log += getSensorTypeLabel(sensorType); addLog(LOG_LEVEL_ERROR, log); } + #endif return ""; } diff --git a/src/src/Helpers/WebServer_commandHelper.cpp b/src/src/Helpers/WebServer_commandHelper.cpp index 14f1c1b40a..440699bc1d 100644 --- a/src/src/Helpers/WebServer_commandHelper.cpp +++ b/src/src/Helpers/WebServer_commandHelper.cpp @@ -8,8 +8,6 @@ #include "../WebServer/AccessControl.h" -#include - HandledWebCommand_result handle_command_from_web(EventValueSource::Enum source, String& webrequest) { if (!clientIPallowed()) { return HandledWebCommand_result::IP_not_allowed; } @@ -57,11 +55,11 @@ HandledWebCommand_result handle_command_from_web(EventValueSource::Enum source, if (sendOK) { if (printToWebJSON) { // Format "OK" to JSON format - const int capacity = JSON_OBJECT_SIZE(2); - StaticJsonDocument root; - root[F("return")] = F("OK"); - root[F("command")] = webrequest; - serializeJson(root, printWebString); + printWebString = F("{\"return\": \""); + printWebString += F("OK"); + printWebString += F("\",\"command\": \""); + printWebString += webrequest; + printWebString += F("\"}"); } else { printWebString = F("OK"); } @@ -71,11 +69,11 @@ HandledWebCommand_result handle_command_from_web(EventValueSource::Enum source, if (printToWebJSON) { // Format error to JSON format - const int capacity = JSON_OBJECT_SIZE(2); - StaticJsonDocument root; - root[F("return")] = F("Unknown or restricted command"); - root[F("command")] = webrequest; - serializeJson(root, printWebString); + printWebString = F("{\"return\": \""); + printWebString += F("Unknown or restricted command"); + printWebString += F("\",\"command\": \""); + printWebString += webrequest; + printWebString += F("\"}"); } return HandledWebCommand_result::Unknown_or_restricted_command; } diff --git a/src/src/Helpers/_CPlugin_DomoticzHelper.cpp b/src/src/Helpers/_CPlugin_DomoticzHelper.cpp index d2cdadf0d9..8b3431c5b3 100644 --- a/src/src/Helpers/_CPlugin_DomoticzHelper.cpp +++ b/src/src/Helpers/_CPlugin_DomoticzHelper.cpp @@ -161,11 +161,15 @@ String formatDomoticzSensorType(struct EventStruct *event) { break; default: { - String log = F("Domoticz Controller: Not yet implemented sensor type: "); - log += static_cast(event->sensorType); - log += F(" idx: "); - log += event->idx; - addLog(LOG_LEVEL_ERROR, log); + #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_ERROR)) { + String log = F("Domoticz Controller: Not yet implemented sensor type: "); + log += static_cast(event->sensorType); + log += F(" idx: "); + log += event->idx; + addLog(LOG_LEVEL_ERROR, log); + } + #endif break; } } @@ -178,13 +182,17 @@ String formatDomoticzSensorType(struct EventStruct *event) { } values.trim(); { - String log = F(" Domoticz: Sensortype: "); - log += static_cast(event->sensorType); - log += F(" idx: "); - log += event->idx; - log += F(" values: "); - log += values; - addLog(LOG_LEVEL_INFO, log); + #ifndef BUILD_NO_DEBUG + if (loglevelActiveFor(LOG_LEVEL_INFO)) { + String log = F(" Domoticz: Sensortype: "); + log += static_cast(event->sensorType); + log += F(" idx: "); + log += event->idx; + log += F(" values: "); + log += values; + addLog(LOG_LEVEL_INFO, log); + } + #endif } return values; } diff --git a/src/src/Static/WebStaticData.cpp b/src/src/Static/WebStaticData.cpp new file mode 100644 index 0000000000..29dce6d821 --- /dev/null +++ b/src/src/Static/WebStaticData.cpp @@ -0,0 +1,121 @@ +#include "../Static/WebStaticData.h" + +#include "../Globals/Cache.h" +#include "../Helpers/ESPEasy_Storage.h" +#include "../WebServer/HTML_wrappers.h" + +String generate_external_URL(const String& fname) { + String url; + url.reserve(80 + fname.length()); + url = F("https://cdn.jsdelivr.net/gh/letscontrolit/ESPEasy@mega-20201130/static/"); + url += fname; + return url; +} + + +void serve_CSS() { + String url = F("esp.css"); + if (!fileExists(url)) + { + #ifndef WEBSERVER_CSS + url = generate_external_URL(F("espeasy_default.css")); + #else + addHtml(F("")); + return; + #endif + } + + addHtml(F("'); +} + +void serve_favicon() { + #ifdef WEBSERVER_FAVICON_CDN + addHtml(F("'); + #endif +} + +void serve_JS(JSfiles_e JSfile) { + String url; + switch (JSfile) { + case JSfiles_e::UpdateSensorValuesDevicePage: + url = F("update_sensor_values_device_page.js"); + break; + case JSfiles_e::FetchAndParseLog: + url = F("fetch_and_parse_log.js"); + break; + case JSfiles_e::SaveRulesFile: + url = F("rules_save.js"); + break; + case JSfiles_e::GitHubClipboard: + url = F("github_clipboard.js"); + break; + case JSfiles_e::Reboot: + url = F("reboot.js"); + break; + case JSfiles_e::Toasting: + url = F("toasting.js"); + break; + } + + if (!fileExists(url)) + { + #ifndef WEBSERVER_INCLUDE_JS + url = generate_external_URL(url); + #else + html_add_script(true); + switch (JSfile) { + case JSfiles_e::UpdateSensorValuesDevicePage: + #ifdef WEBSERVER_DEVICES + TXBuffer += DATA_UPDATE_SENSOR_VALUES_DEVICE_PAGE_JS; + #endif + break; + case JSfiles_e::FetchAndParseLog: + #ifdef WEBSERVER_LOG + TXBuffer += DATA_FETCH_AND_PARSE_LOG_JS; + #endif + break; + case JSfiles_e::SaveRulesFile: + #ifdef WEBSERVER_RULES + TXBuffer += jsSaveRules; + #endif + break; + case JSfiles_e::GitHubClipboard: + #ifdef WEBSERVER_GITHUB_COPY + TXBuffer += DATA_GITHUB_CLIPBOARD_JS; + #endif + break; + case JSfiles_e::Reboot: + TXBuffer += DATA_REBOOT_JS; + break; + case JSfiles_e::Toasting: + TXBuffer += jsToastMessageBegin; + // we can push custom messages here in future releases... + addHtml(F("Submitted")); + TXBuffer += jsToastMessageEnd; + break; + + } + html_add_script_end(); + return; + #endif + } + addHtml(F("'); + html_add_script_end(); +} \ No newline at end of file diff --git a/src/src/Static/WebStaticData.h b/src/src/Static/WebStaticData.h index b46967a98e..da41c2e8a8 100644 --- a/src/src/Static/WebStaticData.h +++ b/src/src/Static/WebStaticData.h @@ -7,6 +7,25 @@ //-V::569 +String generate_external_URL(const String& fname); + +void serve_CSS(); + +void serve_favicon(); + +enum class JSfiles_e { + UpdateSensorValuesDevicePage, + FetchAndParseLog, + SaveRulesFile, + GitHubClipboard, + Reboot, + Toasting, + +}; + +void serve_JS(JSfiles_e JSfile); + + #ifdef WEBSERVER_FAVICON /*********************************************************************************************\ * ESP Easy logo Favicon.ico 16x16 8 bit @@ -64,12 +83,15 @@ static const char DATA_GITHUB_CLIPBOARD_JS[] PROGMEM = {0x66,0x75,0x6e,0x63,0x74 #endif +#ifdef WEBSERVER_CSS static const char DATA_ESPEASY_DEFAULT_MIN_CSS[] PROGMEM = {0x2e,0x63,0x6c,0x6f,0x73,0x65,0x62,0x74,0x6e,0x2c,0x68,0x31,0x2c,0x68,0x32,0x2c,0x68,0x33,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x77,0x65,0x69,0x67,0x68,0x74,0x3a,0x37,0x30,0x30,0x7d,0x68,0x31,0x2c,0x68,0x36,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x37,0x44,0x7d,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x2c,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x7b,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3a,0x27,0x27,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2c,0x2e,0x6d,0x65,0x6e,0x75,0x7b,0x74,0x65,0x78,0x74,0x2d,0x64,0x65,0x63,0x6f,0x72,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x6e,0x6f,0x6e,0x65,0x7d,0x2e,0x64,0x69,0x76,0x5f,0x6c,0x2c,0x2e,0x6d,0x65,0x6e,0x75,0x7b,0x66,0x6c,0x6f,0x61,0x74,0x3a,0x6c,0x65,0x66,0x74,0x7d,0x2e,0x63,0x6c,0x6f,0x73,0x65,0x62,0x74,0x6e,0x2c,0x2e,0x64,0x69,0x76,0x5f,0x72,0x7b,0x66,0x6c,0x6f,0x61,0x74,0x3a,0x72,0x69,0x67,0x68,0x74,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x66,0x66,0x66,0x7d,0x2a,0x7b,0x62,0x6f,0x78,0x2d,0x73,0x69,0x7a,0x69,0x6e,0x67,0x3a,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x62,0x6f,0x78,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x73,0x61,0x6e,0x73,0x2d,0x73,0x65,0x72,0x69,0x66,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x32,0x70,0x74,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x30,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x30,0x7d,0x68,0x31,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x36,0x70,0x74,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x38,0x70,0x78,0x20,0x30,0x7d,0x68,0x32,0x2c,0x68,0x33,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x32,0x70,0x74,0x7d,0x68,0x32,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x34,0x34,0x34,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x46,0x46,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x30,0x20,0x2d,0x34,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x36,0x70,0x78,0x7d,0x68,0x33,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x45,0x45,0x45,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x34,0x34,0x34,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x31,0x36,0x70,0x78,0x20,0x2d,0x34,0x70,0x78,0x20,0x30,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x7d,0x68,0x36,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x30,0x70,0x74,0x7d,0x63,0x6f,0x64,0x65,0x2c,0x6b,0x62,0x64,0x2c,0x70,0x72,0x65,0x2c,0x73,0x61,0x6d,0x70,0x2c,0x74,0x74,0x2c,0x78,0x6d,0x70,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x6d,0x6f,0x6e,0x6f,0x73,0x70,0x61,0x63,0x65,0x2c,0x6d,0x6f,0x6e,0x6f,0x73,0x70,0x61,0x63,0x65,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x65,0x6d,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x37,0x44,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x34,0x70,0x78,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x46,0x46,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x34,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x20,0x31,0x36,0x70,0x78,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2e,0x68,0x65,0x6c,0x70,0x2c,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x2c,0x69,0x6e,0x70,0x75,0x74,0x2c,0x73,0x65,0x6c,0x65,0x63,0x74,0x2c,0x74,0x65,0x78,0x74,0x61,0x72,0x65,0x61,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x67,0x72,0x61,0x79,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x73,0x74,0x79,0x6c,0x65,0x3a,0x73,0x6f,0x6c,0x69,0x64,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x70,0x78,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2e,0x6c,0x69,0x6e,0x6b,0x2e,0x77,0x69,0x64,0x65,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x69,0x6e,0x6c,0x69,0x6e,0x65,0x2d,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x30,0x30,0x25,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2e,0x6c,0x69,0x6e,0x6b,0x2e,0x72,0x65,0x64,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x72,0x65,0x64,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2e,0x68,0x65,0x6c,0x70,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x35,0x30,0x25,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x32,0x70,0x78,0x20,0x34,0x70,0x78,0x7d,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x2c,0x69,0x6e,0x70,0x75,0x74,0x2c,0x73,0x65,0x6c,0x65,0x63,0x74,0x2c,0x74,0x65,0x78,0x74,0x61,0x72,0x65,0x61,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x34,0x70,0x78,0x7d,0x2e,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3a,0x68,0x6f,0x76,0x65,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x23,0x33,0x36,0x39,0x7d,0x69,0x6e,0x70,0x75,0x74,0x3a,0x68,0x6f,0x76,0x65,0x72,0x2c,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x68,0x6f,0x76,0x65,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x63,0x63,0x63,0x7d,0x69,0x6e,0x70,0x75,0x74,0x2c,0x73,0x65,0x6c,0x65,0x63,0x74,0x2c,0x74,0x65,0x78,0x74,0x61,0x72,0x65,0x61,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x65,0x65,0x65,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x34,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x20,0x38,0x70,0x78,0x7d,0x69,0x6e,0x70,0x75,0x74,0x2e,0x77,0x69,0x64,0x65,0x2c,0x73,0x65,0x6c,0x65,0x63,0x74,0x2e,0x77,0x69,0x64,0x65,0x7b,0x6d,0x61,0x78,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x35,0x30,0x30,0x70,0x78,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x38,0x30,0x25,0x7d,0x2e,0x77,0x69,0x64,0x65,0x6e,0x75,0x6d,0x62,0x65,0x72,0x7b,0x6d,0x61,0x78,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x35,0x30,0x30,0x70,0x78,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x30,0x30,0x70,0x78,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x2c,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x32,0x70,0x74,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x2d,0x6c,0x65,0x66,0x74,0x3a,0x33,0x35,0x70,0x78,0x3b,0x63,0x75,0x72,0x73,0x6f,0x72,0x3a,0x70,0x6f,0x69,0x6e,0x74,0x65,0x72,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x7b,0x2d,0x6d,0x6f,0x7a,0x2d,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x2d,0x6d,0x73,0x2d,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x62,0x6c,0x6f,0x63,0x6b,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x6c,0x65,0x66,0x74,0x3a,0x34,0x70,0x78,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x74,0x6f,0x70,0x3a,0x30,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x72,0x65,0x6c,0x61,0x74,0x69,0x76,0x65,0x3b,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x20,0x69,0x6e,0x70,0x75,0x74,0x7b,0x63,0x75,0x72,0x73,0x6f,0x72,0x3a,0x70,0x6f,0x69,0x6e,0x74,0x65,0x72,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x7d,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x2e,0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x64,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x67,0x72,0x65,0x79,0x7d,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x65,0x65,0x65,0x3b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x32,0x35,0x70,0x78,0x3b,0x6c,0x65,0x66,0x74,0x3a,0x30,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x3b,0x74,0x6f,0x70,0x3a,0x30,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x32,0x35,0x70,0x78,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x3a,0x68,0x6f,0x76,0x65,0x72,0x20,0x69,0x6e,0x70,0x75,0x74,0x7e,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x63,0x63,0x63,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x20,0x69,0x6e,0x70,0x75,0x74,0x3a,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x7e,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x37,0x44,0x7d,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x20,0x69,0x6e,0x70,0x75,0x74,0x3a,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x7e,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x2c,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x62,0x6c,0x6f,0x63,0x6b,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x20,0x2e,0x63,0x68,0x65,0x63,0x6b,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x7b,0x2d,0x6d,0x73,0x2d,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3a,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x34,0x35,0x64,0x65,0x67,0x29,0x3b,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3a,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x34,0x35,0x64,0x65,0x67,0x29,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x73,0x6f,0x6c,0x69,0x64,0x20,0x23,0x66,0x66,0x66,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x30,0x20,0x33,0x70,0x78,0x20,0x33,0x70,0x78,0x20,0x30,0x3b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x31,0x30,0x70,0x78,0x3b,0x6c,0x65,0x66,0x74,0x3a,0x37,0x70,0x78,0x3b,0x74,0x6f,0x70,0x3a,0x33,0x70,0x78,0x3b,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3a,0x72,0x6f,0x74,0x61,0x74,0x65,0x28,0x34,0x35,0x64,0x65,0x67,0x29,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x35,0x70,0x78,0x7d,0x23,0x74,0x6f,0x61,0x73,0x74,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x2c,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x2c,0x2e,0x6c,0x6f,0x67,0x76,0x69,0x65,0x77,0x65,0x72,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x67,0x72,0x61,0x79,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x73,0x74,0x79,0x6c,0x65,0x3a,0x73,0x6f,0x6c,0x69,0x64,0x7d,0x23,0x74,0x6f,0x61,0x73,0x74,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x2c,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x70,0x78,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x7b,0x2d,0x6d,0x6f,0x7a,0x2d,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x2d,0x6d,0x73,0x2d,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x32,0x30,0x70,0x78,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x6c,0x65,0x66,0x74,0x3a,0x39,0x70,0x78,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x72,0x65,0x6c,0x61,0x74,0x69,0x76,0x65,0x3b,0x75,0x73,0x65,0x72,0x2d,0x73,0x65,0x6c,0x65,0x63,0x74,0x3a,0x6e,0x6f,0x6e,0x65,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x7b,0x63,0x75,0x72,0x73,0x6f,0x72,0x3a,0x70,0x6f,0x69,0x6e,0x74,0x65,0x72,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x7d,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x65,0x65,0x65,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x35,0x30,0x25,0x3b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x32,0x36,0x70,0x78,0x3b,0x6c,0x65,0x66,0x74,0x3a,0x30,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x3b,0x74,0x6f,0x70,0x3a,0x30,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x32,0x36,0x70,0x78,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x3a,0x68,0x6f,0x76,0x65,0x72,0x20,0x69,0x6e,0x70,0x75,0x74,0x7e,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x63,0x63,0x63,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x3a,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x7e,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x37,0x44,0x7d,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x6e,0x6f,0x6e,0x65,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x61,0x62,0x73,0x6f,0x6c,0x75,0x74,0x65,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x20,0x69,0x6e,0x70,0x75,0x74,0x3a,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x7e,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x62,0x6c,0x6f,0x63,0x6b,0x7d,0x2e,0x63,0x6f,0x6e,0x74,0x61,0x69,0x6e,0x65,0x72,0x32,0x20,0x2e,0x64,0x6f,0x74,0x6d,0x61,0x72,0x6b,0x3a,0x61,0x66,0x74,0x65,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x23,0x66,0x66,0x66,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x35,0x30,0x25,0x3b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x38,0x70,0x78,0x3b,0x6c,0x65,0x66,0x74,0x3a,0x38,0x70,0x78,0x3b,0x74,0x6f,0x70,0x3a,0x38,0x70,0x78,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x38,0x70,0x78,0x7d,0x2e,0x6c,0x6f,0x67,0x76,0x69,0x65,0x77,0x65,0x72,0x2c,0x74,0x65,0x78,0x74,0x61,0x72,0x65,0x61,0x7b,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x27,0x4c,0x75,0x63,0x69,0x64,0x61,0x20,0x43,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x27,0x2c,0x4d,0x6f,0x6e,0x61,0x63,0x6f,0x2c,0x6d,0x6f,0x6e,0x6f,0x73,0x70,0x61,0x63,0x65,0x3b,0x6d,0x61,0x78,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x30,0x30,0x30,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x20,0x38,0x70,0x78,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x38,0x30,0x25,0x7d,0x23,0x74,0x6f,0x61,0x73,0x74,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x37,0x44,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x34,0x70,0x78,0x3b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x33,0x30,0x25,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x66,0x66,0x66,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x31,0x37,0x70,0x78,0x3b,0x6c,0x65,0x66,0x74,0x3a,0x32,0x38,0x32,0x70,0x78,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x6c,0x65,0x66,0x74,0x3a,0x2d,0x31,0x32,0x35,0x70,0x78,0x3b,0x6d,0x69,0x6e,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x32,0x35,0x30,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x31,0x36,0x70,0x78,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x66,0x69,0x78,0x65,0x64,0x3b,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x76,0x69,0x73,0x69,0x62,0x69,0x6c,0x69,0x74,0x79,0x3a,0x68,0x69,0x64,0x64,0x65,0x6e,0x3b,0x7a,0x2d,0x69,0x6e,0x64,0x65,0x78,0x3a,0x31,0x7d,0x23,0x74,0x6f,0x61,0x73,0x74,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x2e,0x73,0x68,0x6f,0x77,0x7b,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x61,0x6e,0x69,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x66,0x61,0x64,0x65,0x69,0x6e,0x20,0x2e,0x35,0x73,0x2c,0x66,0x61,0x64,0x65,0x6f,0x75,0x74,0x20,0x2e,0x35,0x73,0x20,0x32,0x2e,0x35,0x73,0x3b,0x61,0x6e,0x69,0x6d,0x61,0x74,0x69,0x6f,0x6e,0x3a,0x66,0x61,0x64,0x65,0x69,0x6e,0x20,0x2e,0x35,0x73,0x2c,0x66,0x61,0x64,0x65,0x6f,0x75,0x74,0x20,0x2e,0x35,0x73,0x20,0x32,0x2e,0x35,0x73,0x3b,0x76,0x69,0x73,0x69,0x62,0x69,0x6c,0x69,0x74,0x79,0x3a,0x76,0x69,0x73,0x69,0x62,0x6c,0x65,0x7d,0x40,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x6b,0x65,0x79,0x66,0x72,0x61,0x6d,0x65,0x73,0x20,0x66,0x61,0x64,0x65,0x69,0x6e,0x7b,0x66,0x72,0x6f,0x6d,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x32,0x30,0x25,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x7d,0x74,0x6f,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x33,0x30,0x25,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e,0x39,0x7d,0x7d,0x40,0x6b,0x65,0x79,0x66,0x72,0x61,0x6d,0x65,0x73,0x20,0x66,0x61,0x64,0x65,0x69,0x6e,0x7b,0x66,0x72,0x6f,0x6d,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x32,0x30,0x25,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x7d,0x74,0x6f,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x33,0x30,0x25,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e,0x39,0x7d,0x7d,0x40,0x2d,0x77,0x65,0x62,0x6b,0x69,0x74,0x2d,0x6b,0x65,0x79,0x66,0x72,0x61,0x6d,0x65,0x73,0x20,0x66,0x61,0x64,0x65,0x6f,0x75,0x74,0x7b,0x66,0x72,0x6f,0x6d,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x33,0x30,0x25,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e,0x39,0x7d,0x74,0x6f,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x30,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x7d,0x7d,0x40,0x6b,0x65,0x79,0x66,0x72,0x61,0x6d,0x65,0x73,0x20,0x66,0x61,0x64,0x65,0x6f,0x75,0x74,0x7b,0x66,0x72,0x6f,0x6d,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x33,0x30,0x25,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x2e,0x39,0x7d,0x74,0x6f,0x7b,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x30,0x3b,0x6f,0x70,0x61,0x63,0x69,0x74,0x79,0x3a,0x30,0x7d,0x7d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x30,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x31,0x46,0x31,0x46,0x31,0x7d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x31,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x43,0x46,0x46,0x39,0x35,0x7d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x32,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x39,0x44,0x43,0x45,0x46,0x45,0x7d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x33,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x41,0x34,0x46,0x43,0x37,0x39,0x7d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x34,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x32,0x41,0x42,0x33,0x39,0x7d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x39,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x35,0x30,0x7d,0x2e,0x6c,0x6f,0x67,0x76,0x69,0x65,0x77,0x65,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x32,0x37,0x32,0x37,0x32,0x37,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x31,0x46,0x31,0x46,0x31,0x3b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x35,0x33,0x30,0x70,0x78,0x3b,0x6f,0x76,0x65,0x72,0x66,0x6c,0x6f,0x77,0x3a,0x61,0x75,0x74,0x6f,0x7d,0x74,0x65,0x78,0x74,0x61,0x72,0x65,0x61,0x3a,0x68,0x6f,0x76,0x65,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x63,0x63,0x63,0x7d,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6d,0x75,0x6c,0x74,0x69,0x72,0x6f,0x77,0x20,0x74,0x68,0x2c,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x20,0x74,0x68,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x34,0x34,0x34,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x38,0x38,0x38,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x46,0x46,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x77,0x65,0x69,0x67,0x68,0x74,0x3a,0x37,0x30,0x30,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x36,0x70,0x78,0x3b,0x61,0x6c,0x69,0x67,0x6e,0x2d,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3a,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x63,0x65,0x6e,0x74,0x65,0x72,0x7d,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6d,0x75,0x6c,0x74,0x69,0x72,0x6f,0x77,0x2c,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6c,0x61,0x70,0x73,0x65,0x3a,0x63,0x6f,0x6c,0x6c,0x61,0x70,0x73,0x65,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x30,0x30,0x3b,0x6d,0x69,0x6e,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x34,0x32,0x30,0x70,0x78,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x30,0x30,0x25,0x7d,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6d,0x75,0x6c,0x74,0x69,0x72,0x6f,0x77,0x20,0x74,0x72,0x2c,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x20,0x74,0x64,0x2c,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x20,0x74,0x72,0x7b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x7d,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x20,0x74,0x64,0x7b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x33,0x30,0x70,0x78,0x7d,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6d,0x75,0x6c,0x74,0x69,0x72,0x6f,0x77,0x20,0x74,0x64,0x7b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x33,0x30,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x3b,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x63,0x65,0x6e,0x74,0x65,0x72,0x7d,0x74,0x61,0x62,0x6c,0x65,0x2e,0x6d,0x75,0x6c,0x74,0x69,0x72,0x6f,0x77,0x20,0x74,0x72,0x3a,0x6e,0x74,0x68,0x2d,0x63,0x68,0x69,0x6c,0x64,0x28,0x65,0x76,0x65,0x6e,0x29,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x44,0x45,0x45,0x36,0x46,0x46,0x7d,0x2e,0x68,0x69,0x67,0x68,0x6c,0x69,0x67,0x68,0x74,0x20,0x74,0x64,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x64,0x62,0x66,0x66,0x30,0x30,0x37,0x35,0x7d,0x2e,0x61,0x70,0x68,0x65,0x61,0x64,0x65,0x72,0x2c,0x2e,0x68,0x65,0x61,0x64,0x65,0x72,0x6d,0x65,0x6e,0x75,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x38,0x46,0x38,0x46,0x38,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x38,0x70,0x78,0x20,0x31,0x32,0x70,0x78,0x7d,0x2e,0x6e,0x6f,0x74,0x65,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x34,0x34,0x34,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x74,0x79,0x6c,0x65,0x3a,0x69,0x74,0x61,0x6c,0x69,0x63,0x7d,0x2e,0x68,0x65,0x61,0x64,0x65,0x72,0x6d,0x65,0x6e,0x75,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x31,0x70,0x78,0x20,0x73,0x6f,0x6c,0x69,0x64,0x20,0x23,0x44,0x44,0x44,0x3b,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x39,0x30,0x70,0x78,0x3b,0x6c,0x65,0x66,0x74,0x3a,0x30,0x3b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x66,0x69,0x78,0x65,0x64,0x3b,0x72,0x69,0x67,0x68,0x74,0x3a,0x30,0x3b,0x74,0x6f,0x70,0x3a,0x30,0x3b,0x7a,0x2d,0x69,0x6e,0x64,0x65,0x78,0x3a,0x31,0x7d,0x2e,0x62,0x6f,0x64,0x79,0x6d,0x65,0x6e,0x75,0x7b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x74,0x6f,0x70,0x3a,0x39,0x36,0x70,0x78,0x7d,0x2e,0x6d,0x65,0x6e,0x75,0x62,0x61,0x72,0x7b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x69,0x6e,0x68,0x65,0x72,0x69,0x74,0x3b,0x74,0x6f,0x70,0x3a,0x35,0x35,0x70,0x78,0x7d,0x2e,0x6d,0x65,0x6e,0x75,0x7b,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x73,0x6f,0x6c,0x69,0x64,0x20,0x74,0x72,0x61,0x6e,0x73,0x70,0x61,0x72,0x65,0x6e,0x74,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x34,0x70,0x78,0x20,0x34,0x70,0x78,0x20,0x30,0x20,0x30,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x34,0x70,0x78,0x20,0x31,0x70,0x78,0x20,0x31,0x70,0x78,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x34,0x34,0x34,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x34,0x70,0x78,0x20,0x31,0x36,0x70,0x78,0x20,0x38,0x70,0x78,0x3b,0x77,0x68,0x69,0x74,0x65,0x2d,0x73,0x70,0x61,0x63,0x65,0x3a,0x6e,0x6f,0x77,0x72,0x61,0x70,0x7d,0x2e,0x6d,0x65,0x6e,0x75,0x2e,0x61,0x63,0x74,0x69,0x76,0x65,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x46,0x46,0x46,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x37,0x44,0x20,0x23,0x44,0x44,0x44,0x20,0x23,0x46,0x46,0x46,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x30,0x30,0x7d,0x2e,0x6d,0x65,0x6e,0x75,0x3a,0x68,0x6f,0x76,0x65,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x23,0x44,0x45,0x46,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x30,0x30,0x7d,0x2e,0x6d,0x65,0x6e,0x75,0x5f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x6e,0x6f,0x6e,0x65,0x7d,0x2e,0x6f,0x6e,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x67,0x72,0x65,0x65,0x6e,0x7d,0x2e,0x6f,0x66,0x66,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x72,0x65,0x64,0x7d,0x2e,0x64,0x69,0x76,0x5f,0x72,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x38,0x30,0x3b,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x34,0x70,0x78,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x3a,0x32,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x31,0x70,0x78,0x20,0x31,0x30,0x70,0x78,0x7d,0x2e,0x61,0x6c,0x65,0x72,0x74,0x2c,0x2e,0x77,0x61,0x72,0x6e,0x69,0x6e,0x67,0x7b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x31,0x35,0x70,0x78,0x3b,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x32,0x30,0x70,0x78,0x3b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x66,0x66,0x66,0x7d,0x2e,0x64,0x69,0x76,0x5f,0x62,0x72,0x7b,0x63,0x6c,0x65,0x61,0x72,0x3a,0x62,0x6f,0x74,0x68,0x7d,0x2e,0x61,0x6c,0x65,0x72,0x74,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x66,0x34,0x34,0x33,0x33,0x36,0x7d,0x2e,0x77,0x61,0x72,0x6e,0x69,0x6e,0x67,0x7b,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x66,0x66,0x63,0x61,0x31,0x37,0x7d,0x2e,0x63,0x6c,0x6f,0x73,0x65,0x62,0x74,0x6e,0x7b,0x63,0x75,0x72,0x73,0x6f,0x72,0x3a,0x70,0x6f,0x69,0x6e,0x74,0x65,0x72,0x3b,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x32,0x32,0x70,0x78,0x3b,0x6c,0x69,0x6e,0x65,0x2d,0x68,0x65,0x69,0x67,0x68,0x74,0x3a,0x32,0x30,0x70,0x78,0x3b,0x6d,0x61,0x72,0x67,0x69,0x6e,0x2d,0x6c,0x65,0x66,0x74,0x3a,0x31,0x35,0x70,0x78,0x3b,0x74,0x72,0x61,0x6e,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x2e,0x33,0x73,0x7d,0x2e,0x63,0x6c,0x6f,0x73,0x65,0x62,0x74,0x6e,0x3a,0x68,0x6f,0x76,0x65,0x72,0x7b,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x23,0x30,0x30,0x30,0x7d,0x73,0x65,0x63,0x74,0x69,0x6f,0x6e,0x7b,0x6f,0x76,0x65,0x72,0x66,0x6c,0x6f,0x77,0x2d,0x78,0x3a,0x61,0x75,0x74,0x6f,0x3b,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x30,0x30,0x25,0x7d,0x40,0x6d,0x65,0x64,0x69,0x61,0x20,0x73,0x63,0x72,0x65,0x65,0x6e,0x20,0x61,0x6e,0x64,0x20,0x28,0x6d,0x61,0x78,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x39,0x36,0x30,0x70,0x78,0x29,0x7b,0x2e,0x73,0x68,0x6f,0x77,0x6d,0x65,0x6e,0x75,0x6c,0x61,0x62,0x65,0x6c,0x7b,0x64,0x69,0x73,0x70,0x6c,0x61,0x79,0x3a,0x6e,0x6f,0x6e,0x65,0x7d,0x2e,0x6d,0x65,0x6e,0x75,0x7b,0x6d,0x61,0x78,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x31,0x31,0x76,0x77,0x3b,0x6d,0x61,0x78,0x2d,0x77,0x69,0x64,0x74,0x68,0x3a,0x34,0x38,0x70,0x78,0x7d,0x7d,0x0a, 0}; - +#endif // WEBSERVER_CSS // JavaScript blobs +#ifdef WEBSERVER_INCLUDE_JS static const char DATA_REBOOT_JS[] PROGMEM = {0x69,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x72,0x62,0x74,0x6d,0x73,0x67,0x22,0x29,0x2c,0x69,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x22,0x50,0x6c,0x65,0x61,0x73,0x65,0x20,0x72,0x65,0x62,0x6f,0x6f,0x74,0x3a,0x20,0x3c,0x69,0x6e,0x70,0x75,0x74,0x20,0x69,0x64,0x3d,0x27,0x72,0x65,0x62,0x6f,0x6f,0x74,0x27,0x20,0x63,0x6c,0x61,0x73,0x73,0x3d,0x27,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x6c,0x69,0x6e,0x6b,0x27,0x20,0x76,0x61,0x6c,0x75,0x65,0x3d,0x27,0x52,0x65,0x62,0x6f,0x6f,0x74,0x27,0x20,0x74,0x79,0x70,0x65,0x3d,0x27,0x73,0x75,0x62,0x6d,0x69,0x74,0x27,0x20,0x6f,0x6e,0x63,0x6c,0x69,0x63,0x6b,0x3d,0x27,0x72,0x28,0x29,0x27,0x3e,0x22,0x3b,0x76,0x61,0x72,0x20,0x78,0x3d,0x6e,0x65,0x77,0x20,0x58,0x4d,0x4c,0x48,0x74,0x74,0x70,0x52,0x65,0x71,0x75,0x65,0x73,0x74,0x3b,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x64,0x28,0x29,0x7b,0x69,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x22,0x22,0x2c,0x63,0x6c,0x65,0x61,0x72,0x54,0x69,0x6d,0x65,0x6f,0x75,0x74,0x28,0x74,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x63,0x28,0x29,0x7b,0x69,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x2b,0x3d,0x22,0x2e,0x22,0x2c,0x78,0x2e,0x6f,0x6e,0x6c,0x6f,0x61,0x64,0x3d,0x64,0x2c,0x78,0x2e,0x6f,0x70,0x65,0x6e,0x28,0x22,0x47,0x45,0x54,0x22,0x2c,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x6f,0x72,0x69,0x67,0x69,0x6e,0x29,0x2c,0x78,0x2e,0x73,0x65,0x6e,0x64,0x28,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x62,0x28,0x29,0x7b,0x69,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x22,0x52,0x65,0x62,0x6f,0x6f,0x74,0x69,0x6e,0x67,0x2e,0x2e,0x22,0x2c,0x74,0x3d,0x73,0x65,0x74,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x63,0x2c,0x32,0x65,0x33,0x29,0x7d,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x72,0x28,0x29,0x7b,0x69,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x2b,0x3d,0x22,0x20,0x28,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x29,0x22,0x2c,0x78,0x2e,0x6f,0x6e,0x6c,0x6f,0x61,0x64,0x3d,0x62,0x2c,0x78,0x2e,0x6f,0x70,0x65,0x6e,0x28,0x22,0x47,0x45,0x54,0x22,0x2c,0x77,0x69,0x6e,0x64,0x6f,0x77,0x2e,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x6f,0x72,0x69,0x67,0x69,0x6e,0x2b,0x22,0x2f,0x3f,0x63,0x6d,0x64,0x3d,0x72,0x65,0x62,0x6f,0x6f,0x74,0x22,0x29,0x2c,0x78,0x2e,0x73,0x65,0x6e,0x64,0x28,0x29,0x7d, 0}; +#endif static const char jsToastMessageBegin[] PROGMEM = { "function toasting() {" @@ -116,7 +138,7 @@ static const char jsClipboardCopyPart3[] PROGMEM = { "" }; - +#ifdef WEBSERVER_INCLUDE_JS static const char jsSaveRules[] PROGMEM = { "function saveRulesFile() {" "\"use strict\";" @@ -151,10 +173,14 @@ static const char jsSaveRules[] PROGMEM = { "}});" "}" }; +#endif +#ifdef WEBSERVER_INCLUDE_JS static const char DATA_UPDATE_SENSOR_VALUES_DEVICE_PAGE_JS[] PROGMEM = {0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x65,0x2c,0x73,0x29,0x7b,0x76,0x61,0x72,0x20,0x61,0x2c,0x6c,0x2c,0x6f,0x3d,0x30,0x3b,0x69,0x73,0x4e,0x61,0x4e,0x28,0x73,0x29,0x26,0x26,0x28,0x73,0x3d,0x31,0x29,0x2c,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x65,0x26,0x26,0x28,0x65,0x3d,0x31,0x65,0x33,0x29,0x3b,0x76,0x61,0x72,0x20,0x6e,0x3d,0x73,0x65,0x74,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x6f,0x3e,0x30,0x3f,0x63,0x6c,0x65,0x61,0x72,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x6e,0x29,0x3a,0x2b,0x2b,0x73,0x3e,0x31,0x3f,0x6f,0x3d,0x31,0x3a,0x28,0x66,0x65,0x74,0x63,0x68,0x28,0x22,0x2f,0x6a,0x73,0x6f,0x6e,0x3f,0x76,0x69,0x65,0x77,0x3d,0x73,0x65,0x6e,0x73,0x6f,0x72,0x75,0x70,0x64,0x61,0x74,0x65,0x22,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x73,0x29,0x7b,0x76,0x61,0x72,0x20,0x6f,0x3b,0x32,0x30,0x30,0x3d,0x3d,0x3d,0x73,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x3f,0x73,0x2e,0x6a,0x73,0x6f,0x6e,0x28,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x73,0x29,0x7b,0x66,0x6f,0x72,0x28,0x65,0x3d,0x73,0x2e,0x54,0x54,0x4c,0x2c,0x61,0x3d,0x30,0x3b,0x61,0x3c,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x61,0x2b,0x2b,0x29,0x69,0x66,0x28,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x68,0x61,0x73,0x4f,0x77,0x6e,0x50,0x72,0x6f,0x70,0x65,0x72,0x74,0x79,0x28,0x22,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x22,0x29,0x29,0x66,0x6f,0x72,0x28,0x6c,0x3d,0x30,0x3b,0x6c,0x3c,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x2e,0x6c,0x65,0x6e,0x67,0x74,0x68,0x3b,0x6c,0x2b,0x2b,0x29,0x74,0x72,0x79,0x7b,0x6f,0x3d,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x5b,0x6c,0x5d,0x2e,0x56,0x61,0x6c,0x75,0x65,0x7d,0x63,0x61,0x74,0x63,0x68,0x28,0x65,0x29,0x7b,0x6f,0x3d,0x65,0x2e,0x6e,0x61,0x6d,0x65,0x7d,0x66,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x7b,0x69,0x66,0x28,0x22,0x54,0x79,0x70,0x65,0x45,0x72,0x72,0x6f,0x72,0x22,0x21,0x3d,0x3d,0x6f,0x29,0x7b,0x74,0x65,0x6d,0x70,0x56,0x61,0x6c,0x75,0x65,0x3d,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x5b,0x6c,0x5d,0x2e,0x56,0x61,0x6c,0x75,0x65,0x2c,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x56,0x61,0x6c,0x75,0x65,0x3d,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x5b,0x6c,0x5d,0x2e,0x4e,0x72,0x44,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x2c,0x74,0x65,0x6d,0x70,0x56,0x61,0x6c,0x75,0x65,0x3d,0x70,0x61,0x72,0x73,0x65,0x46,0x6c,0x6f,0x61,0x74,0x28,0x74,0x65,0x6d,0x70,0x56,0x61,0x6c,0x75,0x65,0x29,0x2e,0x74,0x6f,0x46,0x69,0x78,0x65,0x64,0x28,0x64,0x65,0x63,0x69,0x6d,0x61,0x6c,0x73,0x56,0x61,0x6c,0x75,0x65,0x29,0x3b,0x76,0x61,0x72,0x20,0x72,0x3d,0x22,0x76,0x61,0x6c,0x75,0x65,0x5f,0x22,0x2b,0x28,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x4e,0x75,0x6d,0x62,0x65,0x72,0x2d,0x31,0x29,0x2b,0x22,0x5f,0x22,0x2b,0x28,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x5b,0x6c,0x5d,0x2e,0x56,0x61,0x6c,0x75,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x2d,0x31,0x29,0x2c,0x74,0x3d,0x22,0x76,0x61,0x6c,0x75,0x65,0x6e,0x61,0x6d,0x65,0x5f,0x22,0x2b,0x28,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x4e,0x75,0x6d,0x62,0x65,0x72,0x2d,0x31,0x29,0x2b,0x22,0x5f,0x22,0x2b,0x28,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x5b,0x6c,0x5d,0x2e,0x56,0x61,0x6c,0x75,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x2d,0x31,0x29,0x2c,0x75,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x72,0x29,0x2c,0x63,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x74,0x29,0x3b,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x3d,0x75,0x26,0x26,0x28,0x75,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x74,0x65,0x6d,0x70,0x56,0x61,0x6c,0x75,0x65,0x29,0x2c,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x3d,0x63,0x26,0x26,0x28,0x63,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x73,0x2e,0x53,0x65,0x6e,0x73,0x6f,0x72,0x73,0x5b,0x61,0x5d,0x2e,0x54,0x61,0x73,0x6b,0x56,0x61,0x6c,0x75,0x65,0x73,0x5b,0x6c,0x5d,0x2e,0x4e,0x61,0x6d,0x65,0x2b,0x22,0x3a,0x22,0x29,0x7d,0x7d,0x65,0x3d,0x73,0x2e,0x54,0x54,0x4c,0x2c,0x63,0x6c,0x65,0x61,0x72,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x6e,0x29,0x2c,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x65,0x2c,0x30,0x29,0x7d,0x29,0x3a,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x22,0x4c,0x6f,0x6f,0x6b,0x73,0x20,0x6c,0x69,0x6b,0x65,0x20,0x74,0x68,0x65,0x72,0x65,0x20,0x77,0x61,0x73,0x20,0x61,0x20,0x70,0x72,0x6f,0x62,0x6c,0x65,0x6d,0x2e,0x20,0x53,0x74,0x61,0x74,0x75,0x73,0x20,0x43,0x6f,0x64,0x65,0x3a,0x20,0x22,0x2b,0x73,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x29,0x7d,0x29,0x2e,0x63,0x61,0x74,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x73,0x29,0x7b,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x73,0x2e,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x29,0x2c,0x65,0x3d,0x35,0x65,0x33,0x2c,0x63,0x6c,0x65,0x61,0x72,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x6e,0x29,0x2c,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x65,0x2c,0x30,0x29,0x7d,0x29,0x2c,0x6f,0x3d,0x31,0x29,0x7d,0x2c,0x65,0x29,0x7d,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x31,0x65,0x33,0x2c,0x30,0x29,0x3b, 0}; +#endif // WEBSERVER_INCLUDE_JS - +#ifdef WEBSERVER_INCLUDE_JS static const char DATA_FETCH_AND_PARSE_LOG_JS[] PROGMEM = {0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x67,0x65,0x74,0x42,0x72,0x6f,0x77,0x73,0x65,0x72,0x28,0x29,0x7b,0x76,0x61,0x72,0x20,0x65,0x2c,0x6f,0x3d,0x6e,0x61,0x76,0x69,0x67,0x61,0x74,0x6f,0x72,0x2e,0x75,0x73,0x65,0x72,0x41,0x67,0x65,0x6e,0x74,0x2c,0x74,0x3d,0x6f,0x2e,0x6d,0x61,0x74,0x63,0x68,0x28,0x2f,0x28,0x6f,0x70,0x65,0x72,0x61,0x7c,0x63,0x68,0x72,0x6f,0x6d,0x65,0x7c,0x73,0x61,0x66,0x61,0x72,0x69,0x7c,0x66,0x69,0x72,0x65,0x66,0x6f,0x78,0x7c,0x6d,0x73,0x69,0x65,0x7c,0x74,0x72,0x69,0x64,0x65,0x6e,0x74,0x28,0x3f,0x3d,0x5c,0x2f,0x29,0x29,0x5c,0x2f,0x3f,0x5c,0x73,0x2a,0x28,0x5c,0x64,0x2b,0x29,0x2f,0x69,0x29,0x7c,0x7c,0x5b,0x5d,0x3b,0x72,0x65,0x74,0x75,0x72,0x6e,0x2f,0x74,0x72,0x69,0x64,0x65,0x6e,0x74,0x2f,0x69,0x2e,0x74,0x65,0x73,0x74,0x28,0x74,0x5b,0x31,0x5d,0x29,0x3f,0x7b,0x6e,0x61,0x6d,0x65,0x3a,0x22,0x49,0x45,0x22,0x2c,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3a,0x28,0x65,0x3d,0x2f,0x5c,0x62,0x72,0x76,0x5b,0x20,0x3a,0x5d,0x2b,0x28,0x5c,0x64,0x2b,0x29,0x2f,0x67,0x2e,0x65,0x78,0x65,0x63,0x28,0x6f,0x29,0x7c,0x7c,0x5b,0x5d,0x29,0x5b,0x31,0x5d,0x7c,0x7c,0x22,0x22,0x7d,0x3a,0x22,0x43,0x68,0x72,0x6f,0x6d,0x65,0x22,0x3d,0x3d,0x3d,0x74,0x5b,0x31,0x5d,0x26,0x26,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x28,0x65,0x3d,0x6f,0x2e,0x6d,0x61,0x74,0x63,0x68,0x28,0x2f,0x5c,0x62,0x4f,0x50,0x52,0x7c,0x45,0x64,0x67,0x65,0x5c,0x2f,0x28,0x5c,0x64,0x2b,0x29,0x2f,0x29,0x29,0x3f,0x7b,0x6e,0x61,0x6d,0x65,0x3a,0x22,0x4f,0x70,0x65,0x72,0x61,0x22,0x2c,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3a,0x65,0x5b,0x31,0x5d,0x7d,0x3a,0x28,0x74,0x3d,0x74,0x5b,0x32,0x5d,0x3f,0x5b,0x74,0x5b,0x31,0x5d,0x2c,0x74,0x5b,0x32,0x5d,0x5d,0x3a,0x5b,0x6e,0x61,0x76,0x69,0x67,0x61,0x74,0x6f,0x72,0x2e,0x61,0x70,0x70,0x4e,0x61,0x6d,0x65,0x2c,0x6e,0x61,0x76,0x69,0x67,0x61,0x74,0x6f,0x72,0x2e,0x61,0x70,0x70,0x56,0x65,0x72,0x73,0x69,0x6f,0x6e,0x2c,0x22,0x2d,0x3f,0x22,0x5d,0x2c,0x6e,0x75,0x6c,0x6c,0x21,0x3d,0x28,0x65,0x3d,0x6f,0x2e,0x6d,0x61,0x74,0x63,0x68,0x28,0x2f,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x5c,0x2f,0x28,0x5c,0x64,0x2b,0x29,0x2f,0x69,0x29,0x29,0x26,0x26,0x74,0x2e,0x73,0x70,0x6c,0x69,0x63,0x65,0x28,0x31,0x2c,0x31,0x2c,0x65,0x5b,0x31,0x5d,0x29,0x2c,0x7b,0x6e,0x61,0x6d,0x65,0x3a,0x74,0x5b,0x30,0x5d,0x2c,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3a,0x74,0x5b,0x31,0x5d,0x7d,0x29,0x7d,0x76,0x61,0x72,0x20,0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x3d,0x67,0x65,0x74,0x42,0x72,0x6f,0x77,0x73,0x65,0x72,0x28,0x29,0x2c,0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x42,0x72,0x6f,0x77,0x73,0x65,0x72,0x3d,0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x2e,0x6e,0x61,0x6d,0x65,0x2b,0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x2e,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3b,0x28,0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x2e,0x6e,0x61,0x6d,0x65,0x3d,0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x2e,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x3c,0x31,0x32,0x29,0x3f,0x74,0x65,0x78,0x74,0x54,0x6f,0x44,0x69,0x73,0x70,0x6c,0x61,0x79,0x3d,0x22,0x45,0x72,0x72,0x6f,0x72,0x3a,0x20,0x22,0x2b,0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x42,0x72,0x6f,0x77,0x73,0x65,0x72,0x2b,0x22,0x20,0x69,0x73,0x20,0x6e,0x6f,0x74,0x20,0x73,0x75,0x70,0x70,0x6f,0x72,0x74,0x65,0x64,0x21,0x20,0x50,0x6c,0x65,0x61,0x73,0x65,0x20,0x74,0x72,0x79,0x20,0x61,0x20,0x6d,0x6f,0x64,0x65,0x72,0x6e,0x20,0x77,0x65,0x62,0x20,0x62,0x72,0x6f,0x77,0x73,0x65,0x72,0x2e,0x22,0x3a,0x74,0x65,0x78,0x74,0x54,0x6f,0x44,0x69,0x73,0x70,0x6c,0x61,0x79,0x3d,0x22,0x46,0x65,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x6c,0x6f,0x67,0x20,0x65,0x6e,0x74,0x72,0x69,0x65,0x73,0x2e,0x2e,0x2e,0x22,0x2c,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x74,0x65,0x78,0x74,0x54,0x6f,0x44,0x69,0x73,0x70,0x6c,0x61,0x79,0x2c,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x31,0x65,0x33,0x2c,0x30,0x29,0x3b,0x76,0x61,0x72,0x20,0x6c,0x6f,0x67,0x4c,0x65,0x76,0x65,0x6c,0x3d,0x6e,0x65,0x77,0x20,0x41,0x72,0x72,0x61,0x79,0x28,0x22,0x55,0x6e,0x75,0x73,0x65,0x64,0x22,0x2c,0x22,0x45,0x72,0x72,0x6f,0x72,0x22,0x2c,0x22,0x49,0x6e,0x66,0x6f,0x22,0x2c,0x22,0x44,0x65,0x62,0x75,0x67,0x22,0x2c,0x22,0x44,0x65,0x62,0x75,0x67,0x20,0x4d,0x6f,0x72,0x65,0x22,0x2c,0x22,0x55,0x6e,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x22,0x2c,0x22,0x55,0x6e,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x22,0x2c,0x22,0x55,0x6e,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x22,0x2c,0x22,0x55,0x6e,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x22,0x2c,0x22,0x44,0x65,0x62,0x75,0x67,0x20,0x44,0x65,0x76,0x22,0x29,0x3b,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x65,0x2c,0x6f,0x29,0x7b,0x76,0x61,0x72,0x20,0x74,0x2c,0x6e,0x3b,0x69,0x73,0x4e,0x61,0x4e,0x28,0x6f,0x29,0x26,0x26,0x28,0x6f,0x3d,0x31,0x29,0x2c,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x65,0x26,0x26,0x28,0x65,0x3d,0x31,0x65,0x33,0x29,0x2c,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x69,0x6e,0x67,0x5f,0x74,0x79,0x70,0x65,0x3d,0x65,0x3c,0x3d,0x35,0x30,0x30,0x3f,0x22,0x61,0x75,0x74,0x6f,0x22,0x3a,0x22,0x73,0x6d,0x6f,0x6f,0x74,0x68,0x22,0x3b,0x76,0x61,0x72,0x20,0x72,0x3d,0x22,0x22,0x2c,0x6c,0x3d,0x30,0x2c,0x73,0x3d,0x73,0x65,0x74,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x7b,0x6c,0x3e,0x30,0x3f,0x63,0x6c,0x65,0x61,0x72,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x73,0x29,0x3a,0x28,0x2b,0x2b,0x6f,0x3e,0x31,0x3f,0x6c,0x3d,0x31,0x3a,0x66,0x65,0x74,0x63,0x68,0x28,0x22,0x2f,0x6c,0x6f,0x67,0x6a,0x73,0x6f,0x6e,0x22,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6f,0x29,0x7b,0x32,0x30,0x30,0x3d,0x3d,0x3d,0x6f,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x3f,0x6f,0x2e,0x6a,0x73,0x6f,0x6e,0x28,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6f,0x29,0x7b,0x76,0x61,0x72,0x20,0x6c,0x3b,0x66,0x6f,0x72,0x28,0x6e,0x75,0x6c,0x6c,0x3d,0x3d,0x6e,0x26,0x26,0x28,0x6e,0x3d,0x22,0x22,0x29,0x2c,0x74,0x3d,0x30,0x3b,0x74,0x3c,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x6e,0x72,0x45,0x6e,0x74,0x72,0x69,0x65,0x73,0x3b,0x2b,0x2b,0x74,0x29,0x74,0x72,0x79,0x7b,0x6c,0x3d,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x45,0x6e,0x74,0x72,0x69,0x65,0x73,0x5b,0x74,0x5d,0x2e,0x74,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x7d,0x63,0x61,0x74,0x63,0x68,0x28,0x65,0x29,0x7b,0x6c,0x3d,0x65,0x2e,0x6e,0x61,0x6d,0x65,0x7d,0x66,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x7b,0x22,0x54,0x79,0x70,0x65,0x45,0x72,0x72,0x6f,0x72,0x22,0x21,0x3d,0x3d,0x6c,0x26,0x26,0x28,0x72,0x3d,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x45,0x6e,0x74,0x72,0x69,0x65,0x73,0x5b,0x74,0x5d,0x2e,0x74,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x2c,0x6e,0x2b,0x3d,0x22,0x3c,0x64,0x69,0x76,0x20,0x63,0x6c,0x61,0x73,0x73,0x3d,0x6c,0x65,0x76,0x65,0x6c,0x5f,0x22,0x2b,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x45,0x6e,0x74,0x72,0x69,0x65,0x73,0x5b,0x74,0x5d,0x2e,0x6c,0x65,0x76,0x65,0x6c,0x2b,0x22,0x20,0x69,0x64,0x3d,0x22,0x2b,0x72,0x2b,0x27,0x3e,0x3c,0x66,0x6f,0x6e,0x74,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x67,0x72,0x61,0x79,0x22,0x3e,0x27,0x2b,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x45,0x6e,0x74,0x72,0x69,0x65,0x73,0x5b,0x74,0x5d,0x2e,0x74,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x2b,0x22,0x3a,0x3c,0x2f,0x66,0x6f,0x6e,0x74,0x3e,0x20,0x22,0x2b,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x45,0x6e,0x74,0x72,0x69,0x65,0x73,0x5b,0x74,0x5d,0x2e,0x74,0x65,0x78,0x74,0x2b,0x22,0x3c,0x2f,0x64,0x69,0x76,0x3e,0x22,0x29,0x7d,0x65,0x3d,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x54,0x54,0x4c,0x2c,0x22,0x22,0x21,0x3d,0x3d,0x6e,0x26,0x26,0x28,0x22,0x46,0x65,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x6c,0x6f,0x67,0x20,0x65,0x6e,0x74,0x72,0x69,0x65,0x73,0x2e,0x2e,0x2e,0x22,0x3d,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x26,0x26,0x28,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x22,0x22,0x29,0x2c,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x2b,0x3d,0x6e,0x29,0x2c,0x6e,0x3d,0x22,0x22,0x2c,0x61,0x75,0x74,0x6f,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x5f,0x6f,0x6e,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x61,0x75,0x74,0x6f,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x22,0x29,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x2c,0x31,0x3d,0x3d,0x61,0x75,0x74,0x6f,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x5f,0x6f,0x6e,0x26,0x26,0x22,0x22,0x21,0x3d,0x3d,0x72,0x26,0x26,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x72,0x29,0x2e,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x49,0x6e,0x74,0x6f,0x56,0x69,0x65,0x77,0x28,0x7b,0x62,0x65,0x68,0x61,0x76,0x69,0x6f,0x72,0x3a,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x69,0x6e,0x67,0x5f,0x74,0x79,0x70,0x65,0x7d,0x29,0x2c,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x75,0x72,0x72,0x65,0x6e,0x74,0x5f,0x6c,0x6f,0x67,0x6c,0x65,0x76,0x65,0x6c,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x3d,0x22,0x4c,0x6f,0x67,0x67,0x69,0x6e,0x67,0x3a,0x20,0x22,0x2b,0x6c,0x6f,0x67,0x4c,0x65,0x76,0x65,0x6c,0x5b,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x53,0x65,0x74,0x74,0x69,0x6e,0x67,0x73,0x57,0x65,0x62,0x4c,0x6f,0x67,0x4c,0x65,0x76,0x65,0x6c,0x5d,0x2b,0x22,0x20,0x28,0x22,0x2b,0x6f,0x2e,0x4c,0x6f,0x67,0x2e,0x53,0x65,0x74,0x74,0x69,0x6e,0x67,0x73,0x57,0x65,0x62,0x4c,0x6f,0x67,0x4c,0x65,0x76,0x65,0x6c,0x2b,0x22,0x29,0x22,0x2c,0x63,0x6c,0x65,0x61,0x72,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x73,0x29,0x2c,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x65,0x2c,0x30,0x29,0x7d,0x29,0x3a,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x22,0x4c,0x6f,0x6f,0x6b,0x73,0x20,0x6c,0x69,0x6b,0x65,0x20,0x74,0x68,0x65,0x72,0x65,0x20,0x77,0x61,0x73,0x20,0x61,0x20,0x70,0x72,0x6f,0x62,0x6c,0x65,0x6d,0x2e,0x20,0x53,0x74,0x61,0x74,0x75,0x73,0x20,0x43,0x6f,0x64,0x65,0x3a,0x20,0x22,0x2b,0x6f,0x2e,0x73,0x74,0x61,0x74,0x75,0x73,0x29,0x7d,0x29,0x2e,0x63,0x61,0x74,0x63,0x68,0x28,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x6f,0x29,0x7b,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x69,0x6e,0x6e,0x65,0x72,0x48,0x54,0x4d,0x4c,0x2b,0x3d,0x22,0x3c,0x64,0x69,0x76,0x3e,0x3e,0x3e,0x20,0x22,0x2b,0x6f,0x2e,0x6d,0x65,0x73,0x73,0x61,0x67,0x65,0x2b,0x22,0x20,0x3c,0x3c,0x3c,0x2f,0x64,0x69,0x76,0x3e,0x22,0x2c,0x61,0x75,0x74,0x6f,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x5f,0x6f,0x6e,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x61,0x75,0x74,0x6f,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x22,0x29,0x2e,0x63,0x68,0x65,0x63,0x6b,0x65,0x64,0x2c,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x54,0x6f,0x70,0x3d,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x67,0x65,0x74,0x45,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x42,0x79,0x49,0x64,0x28,0x22,0x63,0x6f,0x70,0x79,0x54,0x65,0x78,0x74,0x5f,0x31,0x22,0x29,0x2e,0x73,0x63,0x72,0x6f,0x6c,0x6c,0x48,0x65,0x69,0x67,0x68,0x74,0x2c,0x65,0x3d,0x35,0x65,0x33,0x2c,0x63,0x6c,0x65,0x61,0x72,0x49,0x6e,0x74,0x65,0x72,0x76,0x61,0x6c,0x28,0x73,0x29,0x2c,0x6c,0x6f,0x6f,0x70,0x44,0x65,0x4c,0x6f,0x6f,0x70,0x28,0x65,0x2c,0x30,0x29,0x7d,0x29,0x2c,0x6c,0x3d,0x31,0x29,0x7d,0x2c,0x65,0x29,0x7d, 0}; +#endif // WEBSERVER_INCLUDE_JS #endif // WEBSTATICDATA_h diff --git a/src/src/WebServer/DevicesPage.cpp b/src/src/WebServer/DevicesPage.cpp index b71e2cb542..9b378653a6 100644 --- a/src/src/WebServer/DevicesPage.cpp +++ b/src/src/WebServer/DevicesPage.cpp @@ -355,9 +355,13 @@ void handle_devices_CopySubmittedSettings(taskIndex_t taskIndex, pluginID_t task if ((Device[DeviceIndex].Type == DEVICE_TYPE_SERIAL) || (Device[DeviceIndex].Type == DEVICE_TYPE_SERIAL_PLUS1)) { + #ifdef PLUGIN_USES_SERIAL serialHelper_webformSave(&TempEvent); - } + #else + addLog(LOG_LEVEL_ERROR, F("PLUGIN_USES_SERIAL not defined")); + #endif + } const byte valueCount = getValueCountForTask(taskIndex); @@ -394,9 +398,7 @@ void handle_devices_CopySubmittedSettings(taskIndex_t taskIndex, pluginID_t task // ******************************************************************************** void handle_devicess_ShowAllTasksTable(byte page) { - html_add_script(true); - TXBuffer += DATA_UPDATE_SENSOR_VALUES_DEVICE_PAGE_JS; - html_add_script_end(); + serve_JS(JSfiles_e::UpdateSensorValuesDevicePage); html_table_class_multirow(); html_TR(); html_table_header("", 70); @@ -523,7 +525,12 @@ void handle_devicess_ShowAllTasksTable(byte page) } case DEVICE_TYPE_SERIAL: case DEVICE_TYPE_SERIAL_PLUS1: + #ifdef PLUGIN_USES_SERIAL addHtml(serialHelper_getSerialTypeLabel(&TempEvent)); + #else + addHtml(F("PLUGIN_USES_SERIAL not defined")); + #endif + break; default: @@ -627,8 +634,12 @@ void handle_devicess_ShowAllTasksTable(byte page) // fallthrough case DEVICE_TYPE_SERIAL: { + #ifdef PLUGIN_USES_SERIAL addHtml(serialHelper_getGpioDescription(static_cast(Settings.TaskDevicePort[x]), Settings.TaskDevicePin1[x], Settings.TaskDevicePin2[x], F("
"))); + #else + addHtml(F("PLUGIN_USES_SERIAL not defined")); + #endif if (showpin3) { html_BR(); @@ -893,7 +904,12 @@ void handle_devices_TaskSettingsPage(taskIndex_t taskIndex, byte page) case DEVICE_TYPE_SERIAL: case DEVICE_TYPE_SERIAL_PLUS1: { + #ifdef PLUGIN_USES_SERIAL devicePage_show_serial_config(taskIndex); + #else + addHtml(F("PLUGIN_USES_SERIAL not defined")); + #endif + break; } diff --git a/src/src/WebServer/LoadFromFS.cpp b/src/src/WebServer/LoadFromFS.cpp index 8279e038a3..c790636a6a 100644 --- a/src/src/WebServer/LoadFromFS.cpp +++ b/src/src/WebServer/LoadFromFS.cpp @@ -62,6 +62,9 @@ bool loadFromFS(boolean spiffs, String path) { if (spiffs) { + if (!fileExists(path)) { + return false; + } fs::File dataFile = tryOpenFile(path.c_str(), "r"); if (!dataFile) { diff --git a/src/src/WebServer/Log.cpp b/src/src/WebServer/Log.cpp index 4e7066a12a..25c162bbf7 100644 --- a/src/src/WebServer/Log.cpp +++ b/src/src/WebServer/Log.cpp @@ -33,9 +33,7 @@ void handle_log() { addCheckBox(F("autoscroll"), true); addHtml(F("
")); - html_add_script(true); - TXBuffer += DATA_FETCH_AND_PARSE_LOG_JS; - html_add_script_end(); + serve_JS(JSfiles_e::FetchAndParseLog); #else // ifdef WEBSERVER_LOG addHtml(F("Not included in build")); diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 469e424977..0fa236dc50 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -45,12 +45,14 @@ void handle_root() { // if index.htm exists on FS serve that one (first check if gziped version exists) if (loadFromFS(true, F("/index.htm.gz"))) { return; } - + #ifdef FEATURE_SD if (loadFromFS(false, F("/index.htm.gz"))) { return; } + #endif if (loadFromFS(true, F("/index.htm"))) { return; } - + #ifdef FEATURE_SD if (loadFromFS(false, F("/index.htm"))) { return; } + #endif TXBuffer.startStream(); String sCommand = web_server.arg(F("cmd")); diff --git a/src/src/WebServer/Rules.cpp b/src/src/WebServer/Rules.cpp index 0acd299cc3..bab4a84725 100644 --- a/src/src/WebServer/Rules.cpp +++ b/src/src/WebServer/Rules.cpp @@ -95,9 +95,7 @@ void handle_rules() { addButton(fileName, F("Download to file")); html_end_table(); - html_add_script(true); - TXBuffer += jsSaveRules; - html_add_script_end(); + serve_JS(JSfiles_e::SaveRulesFile); sendHeadandTail_stdtemplate(true); TXBuffer.endStream(); diff --git a/src/src/WebServer/SysInfoPage.cpp b/src/src/WebServer/SysInfoPage.cpp index 3c52c8eba4..fdb305e3f1 100644 --- a/src/src/WebServer/SysInfoPage.cpp +++ b/src/src/WebServer/SysInfoPage.cpp @@ -251,9 +251,8 @@ void handle_sysinfo() { addCopyButton(F("copyText"), F("\\n"), F("Copy info to clipboard")); TXBuffer += githublogo; - html_add_script(false); - TXBuffer += DATA_GITHUB_CLIPBOARD_JS; - html_add_script_end(); + serve_JS(JSfiles_e::GitHubClipboard); + # else // ifdef WEBSERVER_GITHUB_COPY addFormHeader(F("System Info")); @@ -682,7 +681,7 @@ void handle_sysinfo_Storage() { html += F(" kB free)"); addHtml(html); } - + #ifndef LIMIT_BUILD_SIZE addRowLabel(F("Page size")); addHtml(String(SpiffsPagesize())); @@ -704,6 +703,7 @@ void handle_sysinfo_Storage() { # endif // if defined(ESP8266) } + #endif # ifndef BUILD_MINIMAL_OTA diff --git a/src/src/WebServer/UploadPage.cpp b/src/src/WebServer/UploadPage.cpp index 301aad0d6d..7e2993d8f7 100644 --- a/src/src/WebServer/UploadPage.cpp +++ b/src/src/WebServer/UploadPage.cpp @@ -4,6 +4,7 @@ #include "../WebServer/AccessControl.h" #include "../WebServer/HTML_wrappers.h" +#include "../Globals/Cache.h" #include "../Helpers/ESPEasy_Storage.h" #include "../../ESPEasy-Globals.h" @@ -14,7 +15,8 @@ // ******************************************************************************** // Web Interface upload page // ******************************************************************************** -byte uploadResult = 0; +uploadResult_e uploadResult = uploadResult_e::UploadStarted; + void handle_upload() { if (!isLoggedIn()) { return; } navMenuIndex = MENU_INDEX_TOOLS; @@ -43,22 +45,22 @@ void handle_upload_post() { TXBuffer.startStream(); sendHeadandTail_stdtemplate(); - - if (uploadResult == 1) - { - addHtml(F("Upload OK!
You may need to reboot to apply all settings...")); - LoadSettings(); - } - - if (uploadResult == 2) { - addHtml(F("Upload file invalid!")); - } - - if (uploadResult == 3) { - addHtml(F("No filename!")); + switch (uploadResult) { + case uploadResult_e::Success: + addHtml(F("Upload OK!
You may need to reboot to apply all settings...")); + clearAllCaches(); + LoadSettings(); + break; + case uploadResult_e::InvalidFile: + addHtml(F("Upload file invalid!")); + break; + case uploadResult_e::NoFilename: + addHtml(F("No filename!")); + break; + case uploadResult_e::UploadStarted: + break; } - addHtml(F("Upload finished")); sendHeadandTail_stdtemplate(true); TXBuffer.endStream(); @@ -71,7 +73,7 @@ void handle_upload_json() { #ifndef BUILD_NO_RAM_TRACKER checkRAM(F("handle_upload_post")); #endif - uint8_t result = uploadResult; + uint8_t result = static_cast(uploadResult); if (!isLoggedIn()) { result = 255; } @@ -102,7 +104,7 @@ void handleFileUpload() { if (upload.filename.c_str()[0] == 0) { - uploadResult = 3; + uploadResult = uploadResult_e::NoFilename; return; } @@ -114,7 +116,7 @@ void handleFileUpload() { addLog(LOG_LEVEL_INFO, log); } valid = false; - uploadResult = 0; + uploadResult = uploadResult_e::UploadStarted; } else if (upload.status == UPLOAD_FILE_WRITE) { @@ -180,10 +182,10 @@ void handleFileUpload() { } if (valid) { - uploadResult = 1; + uploadResult = uploadResult_e::Success; } else { - uploadResult = 2; + uploadResult = uploadResult_e::InvalidFile; } } diff --git a/src/src/WebServer/UploadPage.h b/src/src/WebServer/UploadPage.h index 2abc421c0f..7f6805b4ef 100644 --- a/src/src/WebServer/UploadPage.h +++ b/src/src/WebServer/UploadPage.h @@ -8,7 +8,16 @@ // ******************************************************************************** // Web Interface upload page // ******************************************************************************** -extern byte uploadResult; +enum class uploadResult_e { + // Int values are used in JSON, so keep them numbered like this. + UploadStarted = 0, + Success = 1, + InvalidFile = 2, + NoFilename = 3 +}; + +extern uploadResult_e uploadResult; + void handle_upload(); // ******************************************************************************** diff --git a/src/src/WebServer/WebServer.cpp b/src/src/WebServer/WebServer.cpp index 4b68340f38..bc31c597a4 100644 --- a/src/src/WebServer/WebServer.cpp +++ b/src/src/WebServer/WebServer.cpp @@ -144,9 +144,7 @@ void sendHeadandTail(const String& tmplName, boolean Tail, boolean rebooting) { if (shouldReboot) { // we only add this here as a seperate chunk to prevent using too much memory at once - html_add_script(false); - TXBuffer += DATA_REBOOT_JS; - html_add_script_end(); + serve_JS(JSfiles_e::Reboot); } STOP_TIMER(HANDLE_SERVING_WEBPAGE); } @@ -159,6 +157,7 @@ void sendHeadandTail_stdtemplate(boolean Tail, boolean rebooting) { addHtmlError(F("Warning: Connected via AP")); } + #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_INFO)) { const int nrArgs = web_server.args(); @@ -176,6 +175,7 @@ void sendHeadandTail_stdtemplate(boolean Tail, boolean rebooting) { addLog(LOG_LEVEL_INFO, log); } } + #endif } } @@ -559,11 +559,7 @@ void getWebPageTemplateVar(const String& varName) addHtml(F("'); addHtml(getGpMenuIcon(i)); @@ -585,25 +581,17 @@ void getWebPageTemplateVar(const String& varName) else if (varName == F("css")) { - if (fileExists(F("esp.css"))) // now css is written in writeDefaultCSS() to FS and always present - // if (0) //TODO - { - addHtml(F("")); - } - else - { - addHtml(F("")); - } + serve_favicon(); + serve_CSS(); } else if (varName == F("js")) { html_add_autosubmit_form(); + + // FIXME TD-er: Can only call this after tag has been set for the file. + //serve_JS(JSfiles_e::Toasting); html_add_script(false); TXBuffer += jsToastMessageBegin; @@ -626,11 +614,13 @@ void getWebPageTemplateVar(const String& varName) else { + #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_ERROR)) { String log = F("Templ: Unknown Var : "); log += varName; addLog(LOG_LEVEL_ERROR, log); } + #endif // no return string - eat var name } diff --git a/static/espeasy_default.css b/static/espeasy_default.css index f7f8054f11..c2466b0003 100644 --- a/static/espeasy_default.css +++ b/static/espeasy_default.css @@ -1,424 +1,545 @@ -h1,h6{ - color:#07D -} -.checkmark:after,.dotmark:after{ - content:'' -} -.button,.menu{ - text-decoration:none -} -.div_l,.menu{ - float:left -} -*{ - box-sizing:border-box; - font-family:sans-serif; - font-size:12pt; - margin:0; - padding:0 -} -h1{ - font-size:16pt; - font-weight:700; - margin:8px 0 -} -h2,h3{ - font-size:12pt; - font-weight:700 -} -h2{ - background-color:#444; - color:#FFF; - margin:0 -4px; - padding:6px -} -h3{ - background-color:#EEE; - color:#444; - margin:16px -4px 0; - padding:4px -} -h6{ - font-size:10pt -} -code,kbd,pre,samp,tt,xmp{ - font-family:monospace,monospace; - font-size:1em -} -.button{ - background-color:#07D; - border:none; - border-radius:4px; - color:#FFF; - margin:4px; - padding:4px 16px -} -.button.link.wide{ - display:inline-block; - text-align:center; - width:100% -} -.button.link.red{ - background-color:red -} -.button.help{ - border-color:gray; - border-radius:50%; - border-style:solid; - border-width:1px; - padding:2px 4px -} -.checkmark,input,select,textarea{ - border-color:gray; - border-radius:4px; - border-style:solid; - border-width:1px -} -.button:hover{ - background:#369 -} -input:hover,select:hover{ - background-color:#ccc -} -input,select,textarea{ - background-color:#eee; - margin:4px; - padding:4px 8px -} -input.wide, select.wide{ - max-width:500px; - width:80% -} -.widenumber{ - max-width:500px; - width:7em -} -.container,.container2{ - font-size:12pt; - padding-left:35px; - cursor:pointer -} -.container{ - -moz-user-select:none; - -ms-user-select:none; - -webkit-user-select:none; - display:block; - margin-left:4px; - margin-top:0; - position:relative; - user-select:none -} -.container input{ - cursor:pointer; - opacity:0; - position:absolute -} -.checkmark.disabled{ - background-color:grey -} -.checkmark{ - background-color:#eee; - height:25px; - left:0; - position:absolute; - top:0; - width:25px -} -.container:hover input~.checkmark{ - background-color:#ccc -} -.container input:checked~.checkmark{ - background-color:#07D -} -.checkmark:after{ - display:none; - position:absolute -} -.container input:checked~.checkmark:after,.container2{ - display:block -} -.container .checkmark:after{ - -ms-transform:rotate(45deg); - -webkit-transform:rotate(45deg); - border:solid #fff; - border-width:0 3px 3px 0; - height:10px; - left:7px; - top:3px; - transform:rotate(45deg); - width:5px -} -#toastmessage,.dotmark{ - border-width:1px; - border-color:gray; - border-style:solid -} -.container2{ - -moz-user-select:none; - -ms-user-select:none; - -webkit-user-select:none; - margin-bottom:20px; - margin-left:9px; - position:relative; - user-select:none -} -.container2 input{ - cursor:pointer; - opacity:0; - position:absolute -} -.dotmark{ - background-color:#eee; - border-radius:50%; - height:26px; - left:0; - position:absolute; - top:0; - width:26px -} -.container2:hover input~.dotmark{ - background-color:#ccc -} -.container2 input:checked~.dotmark{ - background-color:#07D -} -.dotmark:after{ - display:none; - position:absolute -} -.container2 input:checked~.dotmark:after{ - display:block -} -.container2 .dotmark:after{ - background:#fff; - border-radius:50%; - height:8px; - left:8px; - top:8px; - width:8px -} -.logviewer,textarea{ - font-family:'Lucida Console',Monaco,monospace; - max-width:1000px; - padding:4px 8px; - width:80% -} -#toastmessage{ - background-color:#07D; - border-radius:4px; - bottom:30%; - color:#fff; - font-size:17px; - left:282px; - margin-left:-125px; - min-width:250px; - padding:16px; - position:fixed; - text-align:center; - visibility:hidden; - z-index:1 -} -#toastmessage.show{ - -webkit-animation:fadein .5s,fadeout .5s 2.5s; - animation:fadein .5s,fadeout .5s 2.5s; - visibility:visible -} -@-webkit-keyframes fadein{ - from{ - bottom:20%; - opacity:0 - } - to{ - bottom:30%; - opacity:.9 - } -} -@keyframes fadein{ - from{ - bottom:20%; - opacity:0 - } - to{ - bottom:30%; - opacity:.9 - } -} -@-webkit-keyframes fadeout{ - from{ - bottom:30%; - opacity:.9 - } - to{ - bottom:0; - opacity:0 - } -} -@keyframes fadeout{ - from{ - bottom:30%; - opacity:.9 - } - to{ - bottom:0; - opacity:0 - } -} -.level_0{ - color:#F1F1F1 -} -.level_1{ - color:#FCFF95 -} -.level_2{ - color:#9DCEFE -} -.level_3{ - color:#A4FC79 -} -.level_4{ - color:#F2AB39 -} -.level_9{ - color:#F50 -} -.logviewer{ - background-color:#272727; - border-color:gray; - border-style:solid; - color:#F1F1F1; - height:530px; - overflow:auto -} -textarea:hover{ - background-color:#ccc -} -table.multirow th,table.normal th{ - background-color:#444; - border-color:#888; - color:#FFF; - font-weight:700; - padding:6px; - align-content: center; - text-align:center -} -table.multirow,table.normal{ - border-collapse:collapse; - color:#000; - min-width:420px; - width:100% -} -table.multirow tr,table.normal td,table.normal tr{ - padding:4px -} -table.normal td{ - height:30px -} -table.multirow td{ - height:30px; - padding:4px; - text-align:center -} -table.multirow tr:nth-child(even){ - background-color:#DEE6FF -} -.highlight td{ - background-color:#dbff0075 -} -.apheader,.headermenu{ - background-color:#F8F8F8; - padding:8px 12px -} -.note{ - color:#444; - font-style:italic -} -.headermenu{ - border-bottom:1px solid #DDD; - height:90px; - left:0; - position:fixed; - right:0; - top:0; - z-index:1 -} -.bodymenu{ - margin-top:96px -} -.menubar{ - position:inherit; - top:55px -} -.menu{ - border:solid transparent; - border-radius:4px 4px 0 0; - border-width:4px 1px 1px; - color:#444; - padding:4px 16px 8px; - white-space:nowrap -} -.menu.active{ - background-color:#FFF; - border-color:#07D #DDD #FFF; - color:#000 -} -.menu:hover{ - background:#DEF; - color:#000 -} -.menu_button{ - display:none -} -.on{ - color:green -} -.off{ - color:red -} -.div_r{ - background-color:#080; - border-radius:4px; - color:#fff; - float:right; - margin:2px; - padding:1px 10px -} -.alert,.warning{ - margin-bottom:15px; - padding:20px; - color:#fff -} -.div_br{ - clear:both -} -.alert{ - background-color:#f44336 -} -.warning{ - background-color:#ffca17 -} -.closebtn{ - color:#fff; - cursor:pointer; - float:right; - font-size:22px; - font-weight:700; - line-height:20px; - margin-left:15px; - transition:.3s -} -.closebtn:hover{ - color:#000 -} -section{ - overflow-x:auto; - width:100% -} -@media screen and (max-width:960px){ - .showmenulabel{ - display:none - } - .menu{ - max-width:11vw; - max-width:48px - } -} +.closebtn, +h1, +h2, +h3 { + font-weight: 700 +} + +h1, +h6 { + color: #07D +} + +.checkmark:after, +.dotmark:after { + content: '' +} + +.button, +.menu { + text-decoration: none +} + +.div_l, +.menu { + float: left +} + +.closebtn, +.div_r { + float: right; + color: #fff +} + +* { + box-sizing: border-box; + font-family: sans-serif; + font-size: 12pt; + margin: 0; + padding: 0 +} + +h1 { + font-size: 16pt; + margin: 8px 0 +} + +h2, +h3 { + font-size: 12pt +} + +h2 { + background-color: #444; + color: #FFF; + margin: 0 -4px; + padding: 6px +} + +h3 { + background-color: #EEE; + color: #444; + margin: 16px -4px 0; + padding: 4px +} + +h6 { + font-size: 10pt +} + +code, +kbd, +pre, +samp, +tt, +xmp { + font-family: monospace, monospace; + font-size: 1em +} + +.button { + background-color: #07D; + border: none; + border-radius: 4px; + color: #FFF; + margin: 4px; + padding: 4px 16px +} + +.button.help, +.checkmark, +input, +select, +textarea { + border-color: gray; + border-style: solid; + border-width: 1px +} + +.button.link.wide { + display: inline-block; + text-align: center; + width: 100% +} + +.button.link.red { + background-color: red +} + +.button.help { + border-radius: 50%; + padding: 2px 4px +} + +.checkmark, +input, +select, +textarea { + border-radius: 4px +} + +.button:hover { + background: #369 +} + +input:hover, +select:hover { + background-color: #ccc +} + +input, +select, +textarea { + background-color: #eee; + margin: 4px; + padding: 4px 8px +} + +input.wide, +select.wide { + max-width: 500px; + width: 80% +} + +.widenumber { + max-width: 500px; + width: 100px +} + +.container, +.container2 { + font-size: 12pt; + padding-left: 35px; + cursor: pointer +} + +.container { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + display: block; + margin-left: 4px; + margin-top: 0; + position: relative; + user-select: none +} + +.container input { + cursor: pointer; + opacity: 0; + position: absolute +} + +.checkmark.disabled { + background-color: grey +} + +.checkmark { + background-color: #eee; + height: 25px; + left: 0; + position: absolute; + top: 0; + width: 25px +} + +.container:hover input~.checkmark { + background-color: #ccc +} + +.container input:checked~.checkmark { + background-color: #07D +} + +.checkmark:after { + display: none; + position: absolute +} + +.container input:checked~.checkmark:after, +.container2 { + display: block +} + +.container .checkmark:after { + -ms-transform: rotate(45deg); + -webkit-transform: rotate(45deg); + border: solid #fff; + border-width: 0 3px 3px 0; + height: 10px; + left: 7px; + top: 3px; + transform: rotate(45deg); + width: 5px +} + +#toastmessage, +.dotmark, +.logviewer { + border-color: gray; + border-style: solid +} + +#toastmessage, +.dotmark { + border-width: 1px +} + +.container2 { + -moz-user-select: none; + -ms-user-select: none; + -webkit-user-select: none; + margin-bottom: 20px; + margin-left: 9px; + position: relative; + user-select: none +} + +.container2 input { + cursor: pointer; + opacity: 0; + position: absolute +} + +.dotmark { + background-color: #eee; + border-radius: 50%; + height: 26px; + left: 0; + position: absolute; + top: 0; + width: 26px +} + +.container2:hover input~.dotmark { + background-color: #ccc +} + +.container2 input:checked~.dotmark { + background-color: #07D +} + +.dotmark:after { + display: none; + position: absolute +} + +.container2 input:checked~.dotmark:after { + display: block +} + +.container2 .dotmark:after { + background: #fff; + border-radius: 50%; + height: 8px; + left: 8px; + top: 8px; + width: 8px +} + +.logviewer, +textarea { + font-family: 'Lucida Console', Monaco, monospace; + max-width: 1000px; + padding: 4px 8px; + width: 80% +} + +#toastmessage { + background-color: #07D; + border-radius: 4px; + bottom: 30%; + color: #fff; + font-size: 17px; + left: 282px; + margin-left: -125px; + min-width: 250px; + padding: 16px; + position: fixed; + text-align: center; + visibility: hidden; + z-index: 1 +} + +#toastmessage.show { + -webkit-animation: fadein .5s, fadeout .5s 2.5s; + animation: fadein .5s, fadeout .5s 2.5s; + visibility: visible +} + +@-webkit-keyframes fadein { + from { + bottom: 20%; + opacity: 0 + } + to { + bottom: 30%; + opacity: .9 + } +} + +@keyframes fadein { + from { + bottom: 20%; + opacity: 0 + } + to { + bottom: 30%; + opacity: .9 + } +} + +@-webkit-keyframes fadeout { + from { + bottom: 30%; + opacity: .9 + } + to { + bottom: 0; + opacity: 0 + } +} + +@keyframes fadeout { + from { + bottom: 30%; + opacity: .9 + } + to { + bottom: 0; + opacity: 0 + } +} + +.level_0 { + color: #F1F1F1 +} + +.level_1 { + color: #FCFF95 +} + +.level_2 { + color: #9DCEFE +} + +.level_3 { + color: #A4FC79 +} + +.level_4 { + color: #F2AB39 +} + +.level_9 { + color: #F50 +} + +.logviewer { + background-color: #272727; + color: #F1F1F1; + height: 530px; + overflow: auto +} + +textarea:hover { + background-color: #ccc +} + +table.multirow th, +table.normal th { + background-color: #444; + border-color: #888; + color: #FFF; + font-weight: 700; + padding: 6px; + align-content: center; + text-align: center +} + +table.multirow, +table.normal { + border-collapse: collapse; + color: #000; + min-width: 420px; + width: 100% +} + +table.multirow tr, +table.normal td, +table.normal tr { + padding: 4px +} + +table.normal td { + height: 30px +} + +table.multirow td { + height: 30px; + padding: 4px; + text-align: center +} + +table.multirow tr:nth-child(even) { + background-color: #DEE6FF +} + +.highlight td { + background-color: #dbff0075 +} + +.apheader, +.headermenu { + background-color: #F8F8F8; + padding: 8px 12px +} + +.note { + color: #444; + font-style: italic +} + +.headermenu { + border-bottom: 1px solid #DDD; + height: 90px; + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 1 +} + +.bodymenu { + margin-top: 96px +} + +.menubar { + position: inherit; + top: 55px +} + +.menu { + border: solid transparent; + border-radius: 4px 4px 0 0; + border-width: 4px 1px 1px; + color: #444; + padding: 4px 16px 8px; + white-space: nowrap +} + +.menu.active { + background-color: #FFF; + border-color: #07D #DDD #FFF; + color: #000 +} + +.menu:hover { + background: #DEF; + color: #000 +} + +.menu_button { + display: none +} + +.on { + color: green +} + +.off { + color: red +} + +.div_r { + background-color: #080; + border-radius: 4px; + margin: 2px; + padding: 1px 10px +} + +.alert, +.warning { + margin-bottom: 15px; + padding: 20px; + color: #fff +} + +.div_br { + clear: both +} + +.alert { + background-color: #f44336 +} + +.warning { + background-color: #ffca17 +} + +.closebtn { + cursor: pointer; + font-size: 22px; + line-height: 20px; + margin-left: 15px; + transition: .3s +} + +.closebtn:hover { + color: #000 +} + +section { + overflow-x: auto; + width: 100% +} + +@media screen and (max-width: 960px) { + .showmenulabel { + display: none + } + .menu { + max-width: 11vw; + max-width: 48px + } +} \ No newline at end of file diff --git a/static/fetch_and_parse_log.js b/static/fetch_and_parse_log.js index 872ad2b078..9e2229de2d 100644 --- a/static/fetch_and_parse_log.js +++ b/static/fetch_and_parse_log.js @@ -117,5 +117,4 @@ function loopDeLoop(timeForNext, activeRequests) { }; check = 1; }, timeForNext); -} - +} \ No newline at end of file diff --git a/static/reboot.js b/static/reboot.js index 6e7a095bb0..9051129434 100644 --- a/static/reboot.js +++ b/static/reboot.js @@ -1,33 +1,27 @@ -i = document.getElementById('rbtmsg'); -i.innerHTML = "Please reboot: "; -var x = new XMLHttpRequest(); +i = document.getElementById("rbtmsg"), + i.innerHTML = "Please reboot: "; +var x = new XMLHttpRequest; -//done function d() { - i.innerHTML = ''; - clearTimeout(t); + i.innerHTML = "", + clearTimeout(t) } - -//keep requesting mainpage until no more errors function c() { - i.innerHTML += '.'; - x.onload = d; - x.open('GET', window.location.origin); - x.send(); + i.innerHTML += ".", + x.onload = d, + x.open("GET", window.location.origin), + x.send() } -//rebooting function b() { - i.innerHTML = 'Rebooting..'; - t = setInterval(c, 2000); + i.innerHTML = "Rebooting..", + t = setInterval(c, 2e3) } - -//request reboot function r() { - i.innerHTML += ' (requesting)'; - x.onload = b; - x.open('GET', window.location.origin + '/?cmd=reboot'); - x.send(); -} + i.innerHTML += " (requesting)", + x.onload = b, + x.open("GET", window.location.origin + "/?cmd=reboot"), + x.send() +} \ No newline at end of file diff --git a/static/rules_save.js b/static/rules_save.js index 1b2ccb1fad..8abc0a23a8 100644 --- a/static/rules_save.js +++ b/static/rules_save.js @@ -1,36 +1,34 @@ function saveRulesFile() { - let button = document.getElementById('save_button'); - let size = document.getElementById('size'); - let ruleTextNew = document.getElementById('rules').value; - ruleTextNew = ruleTextNew.replace(/\\r?\\n/g, '\\r\\n'); - let ruleNumber = document.getElementById('set').value; - let ruleTextFileData = new File([ruleTextNew], 'rules' + ruleNumber + '.txt', { - type: 'text/plain' - }); - let formData = new FormData(); - formData.append('file', ruleTextFileData); - formData.append('enctype', 'multipart/form-data'); - let url = '/rules' + ruleNumber + '.txt?callback=' + Date.now(); - fetch(url).then(res => res.text()).then((ruleTextOld) => { - if (ruleTextNew === ruleTextOld) { - console.log('nothing to save...'); - } else { - let url = '/upload'; - fetch(url, { - method: 'POST', - body: formData - }).then( - response => response.text()).then(html => { - let url = '/rules' + ruleNumber + '.txt?callback=' + Date.now(); - fetch(url).then(res => res.text()).then((ruleTextNewCheck) => { - if (ruleTextNew === ruleTextNewCheck) { - toasting(); - size.innerHTML = ruleTextNew.length; - } else { - console.log('error when saving...'); - } - }); - }); - } - }); -}; + "use strict"; + let size = document.getElementById("size"); + let ruleTextNew = document.getElementById("rules").value; + ruleTextNew = ruleTextNew.replace(/\\r?\\n/g, "\\r\\n"); + let ruleNumber = document.getElementById("set").value; + let ruleTextFileData = new File([ruleTextNew], "rules" + ruleNumber + ".txt", { + type: "text/plain" + }); + let formData = new FormData(); + formData.append("file", ruleTextFileData); + formData.append("enctype", "multipart/form-data"); + let url = "/rules" + ruleNumber + ".txt?callback=" + Date.now(); + fetch(url).then(res => res.text()).then(ruleTextOld => { + if (ruleTextNew === ruleTextOld) { + console.log("nothing to save..."); + } else { + fetch("/upload", { + method: "POST", + body: formData + }).then(response => response.text()).then(l => { + let url = "/rules" + ruleNumber + ".txt?callback=" + Date.now(); + fetch(url).then(res => res.text()).then(ruleTextNewCheck => { + if (ruleTextNew === ruleTextNewCheck) { + toasting(); + size.innerHTML = ruleTextNew.length; + } else { + console.log("error when saving..."); + } + }); + }); + } + }); +} \ No newline at end of file diff --git a/static/toasting,js b/static/toasting,js new file mode 100644 index 0000000000..05eae2d3cb --- /dev/null +++ b/static/toasting,js @@ -0,0 +1,9 @@ +function toasting() { + var x = document.getElementById('toastmessage'); + x.innerHTML = 'Submitted'; + x.className = 'show'; + setTimeout(function() { + x.innerHTML = ''; + x.className = x.className.replace('show', ''); + }, 2000); +} From a319a75e6865573ff4842884ac71be67939cdb63 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 21 Dec 2020 02:32:54 +0100 Subject: [PATCH 03/12] [Cleanup] Reduce build size by using iterators for globalMapPortStatus It also makes execution slightly faster. --- src/_P001_Switch.ino | 5 +- src/_P009_MCP.ino | 5 +- src/_P019_PCF8574.ino | 9 ++- src/src/Commands/GPIO.cpp | 28 ++++--- src/src/ESPEasyCore/ESPEasyGPIO.cpp | 18 +++-- src/src/Helpers/Hardware.cpp | 115 +++++++++++++++------------- src/src/Helpers/PortStatus.cpp | 32 ++++---- 7 files changed, 122 insertions(+), 90 deletions(-) diff --git a/src/_P001_Switch.ino b/src/_P001_Switch.ino index 6bcba2de96..9e3716e972 100644 --- a/src/_P001_Switch.ino +++ b/src/_P001_Switch.ino @@ -118,8 +118,9 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string) // @giig1967g: set current task value for taking actions after changes in the task gpio const uint32_t key = createKey(PLUGIN_ID_001, CONFIG_PIN1); - if (existPortStatus(key)) { - globalMapPortStatus[key].previousTask = event->TaskIndex; + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + it->second.previousTask = event->TaskIndex; } { diff --git a/src/_P009_MCP.ino b/src/_P009_MCP.ino index 1bc616f53a..3b34d2095f 100644 --- a/src/_P009_MCP.ino +++ b/src/_P009_MCP.ino @@ -93,8 +93,9 @@ boolean Plugin_009(byte function, struct EventStruct *event, String& string) // @giig1967g: set current task value for taking actions after changes const uint32_t key = createKey(PLUGIN_ID_009, CONFIG_PORT); - if (existPortStatus(key)) { - globalMapPortStatus[key].previousTask = event->TaskIndex; + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + it->second.previousTask = event->TaskIndex; } addFormCheckBox(F("Send Boot state"), F("p009_boot"), PCONFIG(0)); diff --git a/src/_P019_PCF8574.ino b/src/_P019_PCF8574.ino index a356569ddb..995b1d1a87 100644 --- a/src/_P019_PCF8574.ino +++ b/src/_P019_PCF8574.ino @@ -92,8 +92,9 @@ boolean Plugin_019(byte function, struct EventStruct *event, String& string) // @giig1967g: set current task value for taking actions after changes const uint32_t key = createKey(PLUGIN_ID_019, CONFIG_PORT); - if (existPortStatus(key)) { - globalMapPortStatus[key].previousTask = event->TaskIndex; + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + it->second.previousTask = event->TaskIndex; } addFormCheckBox(F("Send Boot state"), F("p019_boot"), PCONFIG(0)); @@ -678,7 +679,9 @@ boolean Plugin_019_Write(byte Par1, byte Par2) for (i = 0; i < 8; i++) { key = createKey(PLUGIN_ID_019, unit + i); - if (existPortStatus(key) && (globalMapPortStatus[key].mode == PIN_MODE_OUTPUT) && (globalMapPortStatus[key].state == 0)) { + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + if ((it->second.mode == PIN_MODE_OUTPUT) && (it->second.state == 0)) { portmask &= ~(1 << i); // set port i = 0 } } diff --git a/src/src/Commands/GPIO.cpp b/src/src/Commands/GPIO.cpp index 3c95a7fe76..2e00193751 100644 --- a/src/src/Commands/GPIO.cpp +++ b/src/src/Commands/GPIO.cpp @@ -292,10 +292,10 @@ String Command_GPIO_Toggle(struct EventStruct *event, const char* Line) byte mode; int8_t state; - if (existPortStatus(key)) - { - mode=globalMapPortStatus.at(key).mode; - state=globalMapPortStatus.at(key).state; + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + mode = it->second.mode; + state = it->second.state; } else { GPIO_Read(pluginID, event->Par1, state); mode = (state==-1)?PIN_MODE_OFFLINE:PIN_MODE_OUTPUT; @@ -418,15 +418,19 @@ void createAndSetPortStatus_Mode_State(uint32_t key, byte newMode, int8_t newSta { // WARNING: operator [] creates an entry in the map if key does not exist + // If it doesn't exist, it is now created. globalMapPortStatus[key].mode = newMode; - globalMapPortStatus[key].command = 1; //set to 1 in order to display the status in the PinStatus page - - //only force events if state has changed - if (globalMapPortStatus[key].state != newState) { - globalMapPortStatus[key].state = newState; - globalMapPortStatus[key].output = newState; - globalMapPortStatus[key].forceEvent = 1; - globalMapPortStatus[key].forceMonitor = 1; + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + // Should always be true, as it would be created if it didn't exist. + it->second.command = 1; //set to 1 in order to display the status in the PinStatus page + //only force events if state has changed + if (it->second.state != newState) { + it->second.state = newState; + it->second.output = newState; + it->second.forceEvent = 1; + it->second.forceMonitor = 1; + } } } diff --git a/src/src/ESPEasyCore/ESPEasyGPIO.cpp b/src/src/ESPEasyCore/ESPEasyGPIO.cpp index e6c66fc3f9..d807b5a5a9 100644 --- a/src/src/ESPEasyCore/ESPEasyGPIO.cpp +++ b/src/src/ESPEasyCore/ESPEasyGPIO.cpp @@ -20,8 +20,9 @@ void GPIO_Internal_Write(int pin, byte value) { if (checkValidPortRange(PLUGIN_GPIO, pin)) { const uint32_t key = createKey(PLUGIN_GPIO, pin); - if (existPortStatus(key)) { - switch (globalMapPortStatus[key].mode) { + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + switch (it->second.mode) { case PIN_MODE_PWM: set_Gpio_PWM(pin, value); break; @@ -49,8 +50,9 @@ bool GPIO_Read_Switch_State(struct EventStruct *event) { if (checkValidPortRange(PLUGIN_GPIO, pin)) { const uint32_t key = createKey(PLUGIN_GPIO, pin); - if (existPortStatus(key)) { - return GPIO_Read_Switch_State(pin, globalMapPortStatus[key].mode); + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + return GPIO_Read_Switch_State(pin, it->second.mode); } } return false; @@ -275,8 +277,12 @@ bool GPIO_PCF_Write(int Par1, byte Par2) for(i=0; i<8; i++){ key = createKey(PLUGIN_PCF,unit+i); - if (existPortStatus(key) && globalMapPortStatus[key].mode == PIN_MODE_OUTPUT && globalMapPortStatus[key].state == 0) - portmask &= ~(1 << i); //set port i = 0 + auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + if (it->second.mode == PIN_MODE_OUTPUT && it->second.state == 0) { + portmask &= ~(1 << i); //set port i = 0 + } + } } key = createKey(PLUGIN_PCF,Par1); diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 4a3b66a54b..109ffd08db 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -37,59 +37,70 @@ void hardwareInit() if (!serialPinConflict) { const uint32_t key = createKey(1, gpio); if (getGpioPullResistor(gpio, hasPullUp, hasPullDown)) { - switch (Settings.getPinBootState(gpio)) - { - case PinBootState::Default_state: - // At startup, pins are configured as INPUT - break; - case PinBootState::Output_low: - pinMode(gpio, OUTPUT); - digitalWrite(gpio, LOW); - globalMapPortStatus[key].state = LOW; - globalMapPortStatus[key].mode = PIN_MODE_OUTPUT; - globalMapPortStatus[key].init = 1; - - // setPinState(1, gpio, PIN_MODE_OUTPUT, LOW); - break; - case PinBootState::Output_high: - pinMode(gpio, OUTPUT); - digitalWrite(gpio, HIGH); - globalMapPortStatus[key].state = HIGH; - globalMapPortStatus[key].mode = PIN_MODE_OUTPUT; - globalMapPortStatus[key].init = 1; - - // setPinState(1, gpio, PIN_MODE_OUTPUT, HIGH); - break; - case PinBootState::Input_pullup: - if (hasPullUp) { - pinMode(gpio, INPUT_PULLUP); - globalMapPortStatus[key].state = 0; - globalMapPortStatus[key].mode = PIN_MODE_INPUT_PULLUP; - globalMapPortStatus[key].init = 1; - } - break; - case PinBootState::Input_pulldown: - if (hasPullDown) { - #ifdef ESP8266 - if (gpio == 16) { - pinMode(gpio, INPUT_PULLDOWN_16); + const PinBootState bootState = Settings.getPinBootState(gpio); + if (bootState != PinBootState::Default_state) { + int8_t state = -1; + uint8_t mode = PIN_MODE_UNDEFINED; + int8_t init = 0; + switch (bootState) + { + case PinBootState::Default_state: + // At startup, pins are configured as INPUT + break; + case PinBootState::Output_low: + pinMode(gpio, OUTPUT); + digitalWrite(gpio, LOW); + state = LOW; + mode = PIN_MODE_OUTPUT; + init = 1; + + // setPinState(1, gpio, PIN_MODE_OUTPUT, LOW); + break; + case PinBootState::Output_high: + pinMode(gpio, OUTPUT); + digitalWrite(gpio, HIGH); + state = HIGH; + mode = PIN_MODE_OUTPUT; + init = 1; + + // setPinState(1, gpio, PIN_MODE_OUTPUT, HIGH); + break; + case PinBootState::Input_pullup: + if (hasPullUp) { + pinMode(gpio, INPUT_PULLUP); + state = 0; + mode = PIN_MODE_INPUT_PULLUP; + init = 1; } - #endif - #ifdef ESP32 - pinMode(gpio, INPUT_PULLDOWN); - #endif - globalMapPortStatus[key].state = 0; - globalMapPortStatus[key].mode = PIN_MODE_INPUT_PULLDOWN; - globalMapPortStatus[key].init = 1; - } - break; - case PinBootState::Input: - pinMode(gpio, INPUT); - globalMapPortStatus[key].state = 0; - globalMapPortStatus[key].mode = PIN_MODE_INPUT; - globalMapPortStatus[key].init = 1; - break; - + break; + case PinBootState::Input_pulldown: + if (hasPullDown) { + #ifdef ESP8266 + if (gpio == 16) { + pinMode(gpio, INPUT_PULLDOWN_16); + } + #endif + #ifdef ESP32 + pinMode(gpio, INPUT_PULLDOWN); + #endif + state = 0; + mode = PIN_MODE_INPUT_PULLDOWN; + init = 1; + } + break; + case PinBootState::Input: + pinMode(gpio, INPUT); + state = 0; + mode = PIN_MODE_INPUT; + init = 1; + break; + + } + if (init == 1) { + globalMapPortStatus[key].state = state; + globalMapPortStatus[key].mode = mode; + globalMapPortStatus[key].init = init; + } } } } diff --git a/src/src/Helpers/PortStatus.cpp b/src/src/Helpers/PortStatus.cpp index aab8dc8b7d..3f8c5a1f89 100644 --- a/src/src/Helpers/PortStatus.cpp +++ b/src/src/Helpers/PortStatus.cpp @@ -26,22 +26,26 @@ bool existPortStatus(uint32_t key) { } void removeTaskFromPort(uint32_t key) { - if (existPortStatus(key)) { - (globalMapPortStatus[key].task > 0) ? globalMapPortStatus[key].task-- : globalMapPortStatus[key].task = 0; + const auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + (it->second.task > 0) ? it->second.task-- : it->second.task = 0; - if ((globalMapPortStatus[key].task <= 0) && (globalMapPortStatus[key].monitor <= 0) && (globalMapPortStatus[key].command <= 0) && - (globalMapPortStatus[key].init <= 0)) { + if ((it->second.task <= 0) && (it->second.monitor <= 0) && (it->second.command <= 0) && + (it->second.init <= 0)) { + // erase using the key, so the iterator can be const globalMapPortStatus.erase(key); } } } void removeMonitorFromPort(uint32_t key) { - if (existPortStatus(key)) { - globalMapPortStatus[key].monitor = 0; + const auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + it->second.monitor = 0; - if ((globalMapPortStatus[key].task <= 0) && (globalMapPortStatus[key].monitor <= 0) && (globalMapPortStatus[key].command <= 0) && - (globalMapPortStatus[key].init <= 0)) { + if ((it->second.task <= 0) && (it->second.monitor <= 0) && (it->second.command <= 0) && + (it->second.init <= 0)) { + // erase using the key, so the iterator can be const globalMapPortStatus.erase(key); } } @@ -147,11 +151,13 @@ String getPinStateJSON(bool search, uint32_t key, const String& log, int16_t noS int16_t value = noSearchValue; bool found = false; - if (search && existPortStatus(key)) - { - mode = globalMapPortStatus[key].mode; - value = globalMapPortStatus[key].getValue(); - found = true; + if (search) { + const auto it = globalMapPortStatus.find(key); + if (it != globalMapPortStatus.end()) { + mode = it->second.mode; + value = it->second.getValue(); + found = true; + } } if (!search || (search && found)) From 0d11afb23f2c97fdf98c6e884a26c3bae9d65b63 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 21 Dec 2020 02:53:47 +0100 Subject: [PATCH 04/12] Fix build issue for P019 (missing brace) --- src/_P019_PCF8574.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/_P019_PCF8574.ino b/src/_P019_PCF8574.ino index 995b1d1a87..610be8cdd0 100644 --- a/src/_P019_PCF8574.ino +++ b/src/_P019_PCF8574.ino @@ -682,7 +682,8 @@ boolean Plugin_019_Write(byte Par1, byte Par2) auto it = globalMapPortStatus.find(key); if (it != globalMapPortStatus.end()) { if ((it->second.mode == PIN_MODE_OUTPUT) && (it->second.state == 0)) { - portmask &= ~(1 << i); // set port i = 0 + portmask &= ~(1 << i); // set port i = 0 + } } } From c98d63fe9c4ea34dd73163b7e46a2a39a356dc71 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 21 Dec 2020 15:11:25 +0100 Subject: [PATCH 05/12] Rename toasting,js to toasting.js --- static/{toasting,js => toasting.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename static/{toasting,js => toasting.js} (100%) diff --git a/static/toasting,js b/static/toasting.js similarity index 100% rename from static/toasting,js rename to static/toasting.js From 04872354363539bac1d09791653170479004a319 Mon Sep 17 00:00:00 2001 From: TD-er Date: Mon, 21 Dec 2020 16:44:38 +0100 Subject: [PATCH 06/12] [Cleanup] Reduce build size of WebPages Lots of recurring nested function calls can be simplified via a convenience function. --- src/src/WebServer/AdvancedConfigPage.cpp | 16 ++-------- src/src/WebServer/Markup.cpp | 4 +++ src/src/WebServer/Markup.h | 2 ++ src/src/WebServer/RootPage.cpp | 14 ++++----- src/src/WebServer/SysInfoPage.cpp | 40 ++++++++++++------------ 5 files changed, 36 insertions(+), 40 deletions(-) diff --git a/src/src/WebServer/AdvancedConfigPage.cpp b/src/src/WebServer/AdvancedConfigPage.cpp index 652c0e626a..6addb2453a 100644 --- a/src/src/WebServer/AdvancedConfigPage.cpp +++ b/src/src/WebServer/AdvancedConfigPage.cpp @@ -30,28 +30,18 @@ void handle_advanced() { TXBuffer.startStream(); sendHeadandTail_stdtemplate(); - int timezone = getFormItemInt(F("timezone")); - int dststartweek = getFormItemInt(F("dststartweek")); - int dststartdow = getFormItemInt(F("dststartdow")); - int dststartmonth = getFormItemInt(F("dststartmonth")); - int dststarthour = getFormItemInt(F("dststarthour")); - int dstendweek = getFormItemInt(F("dstendweek")); - int dstenddow = getFormItemInt(F("dstenddow")); - int dstendmonth = getFormItemInt(F("dstendmonth")); - int dstendhour = getFormItemInt(F("dstendhour")); String edit = web_server.arg(F("edit")); - if (edit.length() != 0) { // Settings.MessageDelay_unused = getFormItemInt(F("messagedelay")); Settings.IP_Octet = web_server.arg(F("ip")).toInt(); strncpy_webserver_arg(Settings.NTPHost, F("ntphost")); - Settings.TimeZone = timezone; - TimeChangeRule dst_start(dststartweek, dststartdow, dststartmonth, dststarthour, timezone); + Settings.TimeZone = getFormItemInt(F("timezone")); + TimeChangeRule dst_start(getFormItemInt(F("dststartweek")), getFormItemInt(F("dststartdow")), getFormItemInt(F("dststartmonth")), getFormItemInt(F("dststarthour")), Settings.TimeZone); if (dst_start.isValid()) { Settings.DST_Start = dst_start.toFlashStoredValue(); } - TimeChangeRule dst_end(dstendweek, dstenddow, dstendmonth, dstendhour, timezone); + TimeChangeRule dst_end(getFormItemInt(F("dstendweek")), getFormItemInt(F("dstenddow")), getFormItemInt(F("dstendmonth")), getFormItemInt(F("dstendhour")), Settings.TimeZone); if (dst_end.isValid()) { Settings.DST_End = dst_end.toFlashStoredValue(); } webArg2ip(F("syslogip"), Settings.Syslog_IP); diff --git a/src/src/WebServer/Markup.cpp b/src/src/WebServer/Markup.cpp index 927c998ca5..318246c49b 100644 --- a/src/src/WebServer/Markup.cpp +++ b/src/src/WebServer/Markup.cpp @@ -189,6 +189,10 @@ void addRowLabel_copy(const String& label) { html_copyText_TD(); } +void addRowLabel(LabelType::Enum label) { + addRowLabel(getLabel(label)); +} + void addRowLabelValue(LabelType::Enum label) { addRowLabel(getLabel(label)); addHtml(getValue(label)); diff --git a/src/src/WebServer/Markup.h b/src/src/WebServer/Markup.h index b4aef42b24..c6fa21f24a 100644 --- a/src/src/WebServer/Markup.h +++ b/src/src/WebServer/Markup.h @@ -58,6 +58,8 @@ void addRowLabel(const String& label, const String& id = ""); // Add a row label and mark it with copy markers to copy it to clipboard. void addRowLabel_copy(const String& label); +void addRowLabel(LabelType::Enum label); + void addRowLabelValue(LabelType::Enum label); void addRowLabelValue_copy(LabelType::Enum label); diff --git a/src/src/WebServer/RootPage.cpp b/src/src/WebServer/RootPage.cpp index 0fa236dc50..f9e7c1829e 100644 --- a/src/src/WebServer/RootPage.cpp +++ b/src/src/WebServer/RootPage.cpp @@ -96,7 +96,7 @@ void handle_root() { addRowLabelValue(LabelType::UNIT_NR); addRowLabelValue(LabelType::GIT_BUILD); - addRowLabel(getLabel(LabelType::LOCAL_TIME)); + addRowLabel(LabelType::LOCAL_TIME); if (node_time.systemTimePresent()) { @@ -106,11 +106,11 @@ void handle_root() { addHtml(F("No system time source")); } - addRowLabel(getLabel(LabelType::UPTIME)); + addRowLabel(LabelType::UPTIME); { addHtml(getExtendedValue(LabelType::UPTIME)); } - addRowLabel(getLabel(LabelType::LOAD_PCT)); + addRowLabel(LabelType::LOAD_PCT); if (wdcounter > 0) { @@ -123,7 +123,7 @@ void handle_root() { addHtml(html); } { - addRowLabel(getLabel(LabelType::FREE_MEM)); + addRowLabel(LabelType::FREE_MEM); String html; html.reserve(64); html += freeMem; @@ -137,7 +137,7 @@ void handle_root() { addHtml(html); } { - addRowLabel(getLabel(LabelType::FREE_STACK)); + addRowLabel(LabelType::FREE_STACK); String html; html.reserve(64); html += String(getCurrentFreeStack()); @@ -152,7 +152,7 @@ void handle_root() { } addRowLabelValue(LabelType::IP_ADDRESS); - addRowLabel(getLabel(LabelType::WIFI_RSSI)); + addRowLabel(LabelType::WIFI_RSSI); if (NetworkConnected()) { @@ -175,7 +175,7 @@ void handle_root() { #ifdef FEATURE_MDNS { - addRowLabel(getLabel(LabelType::M_DNS)); + addRowLabel(LabelType::M_DNS); String html; html.reserve(64); html += F("TaskIndex); - C009_queue_element element(event); - - for (byte x = 0; x < valueCount; x++) - { - element.txt[x] = formatUserVarNoCheck(event, x); - } // FIXME TD-er must define a proper move operator - success = C009_DelayHandler->addToQueue(C009_queue_element(element)); + success = C009_DelayHandler->addToQueue(C009_queue_element(event)); Scheduler.scheduleNextDelayQueue(ESPEasy_Scheduler::IntervalTimer_e::TIMER_C009_DELAY_QUEUE, C009_DelayHandler->getNextScheduleTime()); break; } @@ -144,9 +137,8 @@ bool do_process_c009_delay_queue(int controller_number, const C009_queue_element // Create nested SENSOR json object JsonObject SENSOR = data.createNestedObject(String(F("SENSOR"))); - byte valueCount = getValueCountForTask(element.TaskIndex); // char itemNames[valueCount][2]; - for (byte x = 0; x < valueCount; x++) + for (byte x = 0; x < element.valueCount; x++) { // Each sensor value get an own object (0..n) // sprintf(itemNames[x],"%d",x); diff --git a/src/_C017.ino b/src/_C017.ino index f71ab81f0d..4bb0f32b30 100644 --- a/src/_C017.ino +++ b/src/_C017.ino @@ -62,15 +62,8 @@ bool CPlugin_017(CPlugin::Function function, struct EventStruct *event, String & if (C017_DelayHandler == nullptr) { break; } - byte valueCount = getValueCountForTask(event->TaskIndex); - C017_queue_element element(event); - - for (byte x = 0; x < valueCount; x++) - { - element.txt[x] = formatUserVarNoCheck(event, x); - } // FIXME TD-er must define a proper move operator - success = C017_DelayHandler->addToQueue(C017_queue_element(element)); + success = C017_DelayHandler->addToQueue(C017_queue_element(event)); Scheduler.scheduleNextDelayQueue(ESPEasy_Scheduler::IntervalTimer_e::TIMER_C017_DELAY_QUEUE, C017_DelayHandler->getNextScheduleTime()); break; } @@ -96,8 +89,7 @@ bool do_process_c017_delay_queue(int controller_number, const C017_queue_element bool do_process_c017_delay_queue(int controller_number, const C017_queue_element &element, ControllerSettingsStruct &ControllerSettings) { - byte valueCount = getValueCountForTask(element.TaskIndex); - if (valueCount == 0) + if (element.valueCount == 0) return true; //exit if we don't have anything to send. if (!NetworkConnected(10)) @@ -114,27 +106,30 @@ bool do_process_c017_delay_queue(int controller_number, const C017_queue_element LoadTaskSettings(element.TaskIndex); const size_t capacity = JSON_ARRAY_SIZE(VARS_PER_TASK) + JSON_OBJECT_SIZE(2) + VARS_PER_TASK * JSON_OBJECT_SIZE(3) + VARS_PER_TASK * 50; //Size for esp8266 with 4 variables per task: 288+200 - DynamicJsonDocument root(capacity); - - // Create the schafolding - root[F("request")] = F("sender data"); - JsonArray data = root.createNestedArray(F("data")); - // Populate JSON with the data - for (uint8_t i = 0; i < valueCount; i++) + String JSON_packet_content; { - if (ExtraTaskSettings.TaskDeviceValueNames[i][0] == 0) - continue; //Zabbix will ignore an empty key anyway - JsonObject block = data.createNestedObject(); - block[F("host")] = Settings.Name; // Zabbix hostname, Unit Name for the ESP easy - block[F("key")] = ExtraTaskSettings.TaskDeviceValueNames[i]; // Zabbix item key // Value Name for the ESP easy - block[F("value")] = atof(element.txt[i].c_str()); // ESPeasy supports only floats + // Place the JSON document in a separate scope to have it destructed as soon as it is no longer needed. + DynamicJsonDocument root(capacity); + + // Create the schafolding + root[F("request")] = F("sender data"); + JsonArray data = root.createNestedArray(F("data")); + // Populate JSON with the data + for (uint8_t i = 0; i < element.valueCount; i++) + { + if (ExtraTaskSettings.TaskDeviceValueNames[i][0] == 0) + continue; //Zabbix will ignore an empty key anyway + JsonObject block = data.createNestedObject(); + block[F("host")] = Settings.Name; // Zabbix hostname, Unit Name for the ESP easy + block[F("key")] = ExtraTaskSettings.TaskDeviceValueNames[i]; // Zabbix item key // Value Name for the ESP easy + block[F("value")] = static_cast(atof(element.txt[i].c_str())); // ESPeasy supports only floats + } + serializeJson(root, JSON_packet_content); } // Assemble packet char packet_header[] = "ZBXD\1"; - String JSON_packet_content=""; - serializeJson(root, JSON_packet_content); uint64_t payload_len = JSON_packet_content.length(); // addLog(LOG_LEVEL_INFO, String(F("ZBX: ")) + JSON_packet_content); diff --git a/src/src/ControllerQueue/C004_queue_element.cpp b/src/src/ControllerQueue/C004_queue_element.cpp deleted file mode 100644 index 49aa82e7bb..0000000000 --- a/src/src/ControllerQueue/C004_queue_element.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "../ControllerQueue/C004_queue_element.h" - -#include "../DataStructs/DeviceStruct.h" -#include "../DataStructs/ESPEasy_EventStruct.h" - -#ifdef USES_C004 - -C004_queue_element::C004_queue_element() {} - -C004_queue_element::C004_queue_element(const struct EventStruct *event) : - idx(event->idx), - TaskIndex(event->TaskIndex), - controller_idx(event->ControllerIndex), - sensorType(event->sensorType) { - if (sensorType == Sensor_VType::SENSOR_TYPE_STRING) { - txt = event->String2; - } -} - -size_t C004_queue_element::getSize() const { - return sizeof(*this) + txt.length(); -} - -#endif diff --git a/src/src/ControllerQueue/C004_queue_element.h b/src/src/ControllerQueue/C004_queue_element.h deleted file mode 100644 index fb803c12e4..0000000000 --- a/src/src/ControllerQueue/C004_queue_element.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef CONTROLLERQUEUE_C004_QUEUE_ELEMENT_H -#define CONTROLLERQUEUE_C004_QUEUE_ELEMENT_H - -#include "../../ESPEasy_common.h" -#include "../Globals/CPlugins.h" -#include "../Globals/Plugins.h" -#include "../DataStructs/DeviceStruct.h" - -struct EventStruct; - -#ifdef USES_C004 - -/*********************************************************************************************\ -* C004_queue_element for queueing requests for C004 ThingSpeak. -* Typical use case for Thingspeak is to only send values every N seconds/minutes. -* So we just store everything needed to recreate the event when the time is ready. -\*********************************************************************************************/ -class C004_queue_element { -public: - - C004_queue_element(); - - C004_queue_element(const struct EventStruct *event); - - size_t getSize() const; - - String txt; - int idx = 0; - taskIndex_t TaskIndex = INVALID_TASK_INDEX; - controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX; - Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE; -}; - -#endif //USES_C004 - - -#endif // CONTROLLERQUEUE_C004_QUEUE_ELEMENT_H diff --git a/src/src/ControllerQueue/C009_queue_element.cpp b/src/src/ControllerQueue/C009_queue_element.cpp deleted file mode 100644 index a464b0aea6..0000000000 --- a/src/src/ControllerQueue/C009_queue_element.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "../ControllerQueue/C009_queue_element.h" - -#include "../DataStructs/ESPEasy_EventStruct.h" - -#ifdef USES_C009 - -C009_queue_element::C009_queue_element() {} - -C009_queue_element::C009_queue_element(const struct EventStruct *event) : - idx(event->idx), - TaskIndex(event->TaskIndex), - controller_idx(event->ControllerIndex), - sensorType(event->sensorType) {} - -size_t C009_queue_element::getSize() const { - size_t total = sizeof(*this); - - for (int i = 0; i < VARS_PER_TASK; ++i) { - total += txt[i].length(); - } - return total; -} - -#endif diff --git a/src/src/ControllerQueue/C009_queue_element.h b/src/src/ControllerQueue/C009_queue_element.h deleted file mode 100644 index 2f3b54cdc7..0000000000 --- a/src/src/ControllerQueue/C009_queue_element.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef CONTROLLERQUEUE_C009_QUEUE_ELEMENT_H -#define CONTROLLERQUEUE_C009_QUEUE_ELEMENT_H - -#include "../../ESPEasy_common.h" -#include "../CustomBuild/ESPEasyLimits.h" -#include "../DataStructs/DeviceStruct.h" -#include "../Globals/CPlugins.h" -#include "../Globals/Plugins.h" - -struct EventStruct; - - -#ifdef USES_C009 - -/*********************************************************************************************\ -* C009_queue_element for queueing requests for C009: FHEM HTTP. -\*********************************************************************************************/ -class C009_queue_element { -public: - - C009_queue_element(); - - C009_queue_element(const struct EventStruct *event); - - size_t getSize() const; - - String txt[VARS_PER_TASK]; - int idx = 0; - taskIndex_t TaskIndex = INVALID_TASK_INDEX; - controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX; - Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE; -}; - -#endif //USES_C009 - - -#endif // CONTROLLERQUEUE_C009_QUEUE_ELEMENT_H diff --git a/src/src/ControllerQueue/C017_queue_element.cpp b/src/src/ControllerQueue/C017_queue_element.cpp deleted file mode 100644 index d8dc6e7389..0000000000 --- a/src/src/ControllerQueue/C017_queue_element.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "../ControllerQueue/C017_queue_element.h" - -#include "../DataStructs/ESPEasy_EventStruct.h" - -#ifdef USES_C017 - -C017_queue_element::C017_queue_element() {} - -C017_queue_element::C017_queue_element(const struct EventStruct *event) : - idx(event->idx), - TaskIndex(event->TaskIndex), - controller_idx(event->ControllerIndex), - sensorType(event->sensorType) {} - -size_t C017_queue_element::getSize() const { - size_t total = sizeof(*this); - - for (int i = 0; i < VARS_PER_TASK; ++i) { - total += txt[i].length(); - } - return total; -} - -#endif diff --git a/src/src/ControllerQueue/C017_queue_element.h b/src/src/ControllerQueue/C017_queue_element.h deleted file mode 100644 index dd4a0e8f89..0000000000 --- a/src/src/ControllerQueue/C017_queue_element.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef CONTROLLERQUEUE_C017_QUEUE_ELEMENT_H -#define CONTROLLERQUEUE_C017_QUEUE_ELEMENT_H - -#include "../../ESPEasy_common.h" -#include "../CustomBuild/ESPEasyLimits.h" -#include "../DataStructs/DeviceStruct.h" -#include "../Globals/CPlugins.h" -#include "../Globals/Plugins.h" - -struct EventStruct; - - -#ifdef USES_C017 - -/*********************************************************************************************\ -* C017_queue_element for queueing requests for C017: Zabbix Trapper Protocol. -\*********************************************************************************************/ -class C017_queue_element { -public: - - C017_queue_element(); - - C017_queue_element(const struct EventStruct *event); - - size_t getSize() const; - - String txt[VARS_PER_TASK]; - int idx = 0; - taskIndex_t TaskIndex = INVALID_TASK_INDEX; - controllerIndex_t controller_idx = INVALID_CONTROLLER_INDEX; - Sensor_VType sensorType = Sensor_VType::SENSOR_TYPE_NONE; -}; - -#endif //USES_C017 - - -#endif // CONTROLLERQUEUE_C017_QUEUE_ELEMENT_H diff --git a/src/src/ControllerQueue/DelayQueueElements.cpp b/src/src/ControllerQueue/DelayQueueElements.cpp index 70aab95350..7e0e5aa8da 100644 --- a/src/src/ControllerQueue/DelayQueueElements.cpp +++ b/src/src/ControllerQueue/DelayQueueElements.cpp @@ -56,6 +56,7 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 4) #endif // ifdef USES_C004 #ifdef USES_C007 +# define C007_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 7) #endif // ifdef USES_C007 @@ -71,6 +72,7 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 8) #endif // ifdef USES_C008 #ifdef USES_C009 +# define C009_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO_CPP(00, 9) #endif // ifdef USES_C009 diff --git a/src/src/ControllerQueue/DelayQueueElements.h b/src/src/ControllerQueue/DelayQueueElements.h index bff26fc2e0..e0e9f74d9a 100644 --- a/src/src/ControllerQueue/DelayQueueElements.h +++ b/src/src/ControllerQueue/DelayQueueElements.h @@ -6,8 +6,6 @@ #include "../ControllerQueue/ControllerDelayHandlerStruct.h" -#include "../ControllerQueue/SimpleQueueElement_string_only.h" -#include "../ControllerQueue/queue_element_single_value_base.h" #include "../DataStructs/ControllerSettingsStruct.h" @@ -41,6 +39,7 @@ void exit_mqtt_delay_queue(); * C001_queue_element for queueing requests for C001. \*********************************************************************************************/ #ifdef USES_C001 +#include "../ControllerQueue/SimpleQueueElement_string_only.h" # define C001_queue_element simple_queue_element_string_only DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 1) #endif // ifdef USES_C001 @@ -49,17 +48,20 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 1) * C003_queue_element for queueing requests for C003 Nodo Telnet. \*********************************************************************************************/ #ifdef USES_C003 +#include "../ControllerQueue/SimpleQueueElement_string_only.h" # define C003_queue_element simple_queue_element_string_only DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 3) #endif // ifdef USES_C003 #ifdef USES_C004 -# include "../ControllerQueue/C004_queue_element.h" +# include "../ControllerQueue/queue_element_formatted_uservar.h" +# define C004_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 4) #endif // ifdef USES_C004 #ifdef USES_C007 -# include "../ControllerQueue/C007_queue_element.h" +# include "../ControllerQueue/queue_element_formatted_uservar.h" +# define C007_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 7) #endif // ifdef USES_C007 @@ -70,12 +72,14 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 7) * Using queue_element_single_value_base \*********************************************************************************************/ #ifdef USES_C008 +#include "../ControllerQueue/queue_element_single_value_base.h" # define C008_queue_element queue_element_single_value_base DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 8) #endif // ifdef USES_C008 #ifdef USES_C009 -# include "../ControllerQueue/C009_queue_element.h" +# include "../ControllerQueue/queue_element_formatted_uservar.h" +# define C009_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 9) #endif // ifdef USES_C009 @@ -85,6 +89,7 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(00, 9) * Using queue_element_single_value_base \*********************************************************************************************/ #ifdef USES_C010 +#include "../ControllerQueue/queue_element_single_value_base.h" # define C010_queue_element queue_element_single_value_base DEFINE_Cxxx_DELAY_QUEUE_MACRO( 0, 10) #endif // ifdef USES_C010 @@ -105,6 +110,7 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO( 0, 11) * Using queue_element_single_value_base \*********************************************************************************************/ #ifdef USES_C012 +#include "../ControllerQueue/queue_element_single_value_base.h" # define C012_queue_element queue_element_single_value_base DEFINE_Cxxx_DELAY_QUEUE_MACRO( 0, 12) #endif // ifdef USES_C012 @@ -136,7 +142,8 @@ DEFINE_Cxxx_DELAY_QUEUE_MACRO(0, 16) #ifdef USES_C017 -# include "../ControllerQueue/C017_queue_element.h" +# include "../ControllerQueue/queue_element_formatted_uservar.h" +# define C017_queue_element queue_element_formatted_uservar DEFINE_Cxxx_DELAY_QUEUE_MACRO(0, 17) #endif // ifdef USES_C017 diff --git a/src/src/ControllerQueue/C007_queue_element.cpp b/src/src/ControllerQueue/queue_element_formatted_uservar.cpp similarity index 65% rename from src/src/ControllerQueue/C007_queue_element.cpp rename to src/src/ControllerQueue/queue_element_formatted_uservar.cpp index 064709fa90..84d470efcb 100644 --- a/src/src/ControllerQueue/C007_queue_element.cpp +++ b/src/src/ControllerQueue/queue_element_formatted_uservar.cpp @@ -1,27 +1,25 @@ -#include "../ControllerQueue/C007_queue_element.h" +#include "../ControllerQueue/queue_element_formatted_uservar.h" #include "../DataStructs/ESPEasy_EventStruct.h" #include "../Helpers/StringConverter.h" #include "../../_Plugin_Helper.h" -#ifdef USES_C007 -C007_queue_element::C007_queue_element() {} +queue_element_formatted_uservar::queue_element_formatted_uservar() {} -C007_queue_element::C007_queue_element(EventStruct *event) : +queue_element_formatted_uservar::queue_element_formatted_uservar(EventStruct *event) : idx(event->idx), TaskIndex(event->TaskIndex), controller_idx(event->ControllerIndex), sensorType(event->sensorType) { valueCount = getValueCountForTask(TaskIndex); - for (byte i = 0; i < valueCount; ++i) { txt[i] = formatUserVarNoCheck(event, i); } } -size_t C007_queue_element::getSize() const { +size_t queue_element_formatted_uservar::getSize() const { size_t total = sizeof(*this); for (int i = 0; i < VARS_PER_TASK; ++i) { @@ -29,5 +27,3 @@ size_t C007_queue_element::getSize() const { } return total; } - -#endif // ifdef USES_C007 diff --git a/src/src/ControllerQueue/C007_queue_element.h b/src/src/ControllerQueue/queue_element_formatted_uservar.h similarity index 64% rename from src/src/ControllerQueue/C007_queue_element.h rename to src/src/ControllerQueue/queue_element_formatted_uservar.h index ed3f747282..932d9ea270 100644 --- a/src/src/ControllerQueue/C007_queue_element.h +++ b/src/src/ControllerQueue/queue_element_formatted_uservar.h @@ -1,5 +1,5 @@ -#ifndef CONTROLLERQUEUE_C007_QUEUE_ELEMENT_H -#define CONTROLLERQUEUE_C007_QUEUE_ELEMENT_H +#ifndef CONTROLLERQUEUE_QUEUE_ELEMENT_FORMATTED_USERVAR_H +#define CONTROLLERQUEUE_QUEUE_ELEMENT_FORMATTED_USERVAR_H #include "../../ESPEasy_common.h" #include "../DataStructs/DeviceStruct.h" @@ -9,18 +9,15 @@ struct EventStruct; - -#ifdef USES_C007 - /*********************************************************************************************\ -* C007_queue_element for queueing requests for C007 Emoncms +* For queueing task values already formatted according to the task settings \*********************************************************************************************/ -class C007_queue_element { +class queue_element_formatted_uservar { public: - C007_queue_element(); + queue_element_formatted_uservar(); - C007_queue_element(struct EventStruct *event); + queue_element_formatted_uservar(struct EventStruct *event); size_t getSize() const; @@ -32,6 +29,4 @@ class C007_queue_element { byte valueCount = 0; }; -#endif //USES_C007 - -#endif // CONTROLLERQUEUE_C007_QUEUE_ELEMENT_H +#endif // CONTROLLERQUEUE_QUEUE_ELEMENT_FORMATTED_USERVAR_H From c343c17ec80b87927d5d57dd46a88bd8c2fbb03b Mon Sep 17 00:00:00 2001 From: TD-er Date: Thu, 24 Dec 2020 20:40:43 +0100 Subject: [PATCH 12/12] [PWM] Fix fade down (#3434) Fixes: #3434 --- src/src/Helpers/Hardware.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/src/Helpers/Hardware.cpp b/src/src/Helpers/Hardware.cpp index 109ffd08db..f9a83d5ddd 100644 --- a/src/src/Helpers/Hardware.cpp +++ b/src/src/Helpers/Hardware.cpp @@ -1098,23 +1098,23 @@ bool set_Gpio_PWM(int gpio, uint32_t dutyCycle, uint32_t fadeDuration_ms, uint32 if (fadeDuration_ms != 0) { + const int32_t resolution_factor = (1 << 12); const byte prev_mode = tempStatus.mode; - uint16_t prev_value = tempStatus.getDutyCycle(); + int32_t prev_value = tempStatus.getDutyCycle(); // getPinState(pluginID, gpio, &prev_mode, &prev_value); if (prev_mode != PIN_MODE_PWM) { prev_value = 0; } - int32_t step_value = ((dutyCycle - prev_value) << 12) / fadeDuration_ms; - int32_t curr_value = prev_value << 12; + const int32_t step_value = ((static_cast(dutyCycle) - prev_value) * resolution_factor) / static_cast(fadeDuration_ms); + int32_t curr_value = prev_value * resolution_factor; int i = fadeDuration_ms; while (i--) { curr_value += step_value; - int16_t new_value; - new_value = (uint16_t)(curr_value >> 12); + const int16_t new_value = curr_value / resolution_factor; #if defined(ESP8266) analogWrite(gpio, new_value); #endif // if defined(ESP8266)