diff --git a/dist/Release_notes.txt b/dist/Release_notes.txt index ab33bceb6..721735060 100644 --- a/dist/Release_notes.txt +++ b/dist/Release_notes.txt @@ -1,3 +1,46 @@ +------------------------------------------------- +Changes in release mega-20200410 (since mega-20200328) +------------------------------------------------- + +Release date: vr 10 apr 2020 21:23:29 CEST + +Bartlomiej Zimon (1): + ESP32: add subtarget for genuine units firmware-factory.bin Resolves #2964 #2941 #2486 + +Gijs Noorlander (16): + [Frontend] Fix reload on change for selectors (#2974 ) + [Frontend] Fix crash when loading config + controller page + [CUL Reader] P094_CULReader + [CUL Reader] Clean up code + [CUL Reader] Add 4th filter parameter + [CUL Reader] Fix bug in save/load settings + [CUL Reader] Add positional match + [Sysvar] Fix show %ip% and %ip4% instead of %ip4% twice + [CUL Reader] Add basic docs + [Webserver] Fix ambiguous function definitions for selectors + [Serial Plugins] Share more code among plugins using serial + [Build] Fix build issue + [build] New attempt to fix build for unused static function + [PulseCounter] Restore from RTC before initializing pin triggers + [WiFi] Fix problem with static IP and reconnect ESP32 (#2997) + [WiFi] Switch to default PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 + +Michael Schröder (2): + Fix DeepSleep0 command + Update deepsleep-command docs + +TD-er (2): + [P020_Ser2Net] Fix missing break; PLUGIN_SERIAL_IN + [CUL Reader] 12 items per filter line + extra chars on filter whitelist + +tonhuisman (5): + [P036] Added setting for 'Keep display off receiving text' + [P036] Added setting for 'Wake display on receiving text' + [P036] Added new setting to plugin documentation + Fixed note wording + Made note wording more functional + + ------------------------------------------------- Changes in release mega-20200328 (since mega-20200310) ------------------------------------------------- diff --git a/docs/source/Plugin/P000_commands.repl b/docs/source/Plugin/P000_commands.repl index 89ca3bdf6..55c49e498 100644 --- a/docs/source/Plugin/P000_commands.repl +++ b/docs/source/Plugin/P000_commands.repl @@ -98,6 +98,7 @@ :red:`Internal`"," Switch the node to deep sleep. Max sleep time depends on library version and differs from roughly 71 minutes to 3h46. + If you specify a Min sleep time of 0, you'll have to wake the device yourself by pulling RST to GND. ``DeepSleep,``" " @@ -228,16 +229,6 @@ ``meminfoDetail``" " - MessageDelay"," - :red:`Internal`"," - Get or set the MQTT message delay. - - ``MessageDelay`` - - ``MessageDelay,`` - - Example output: ``MQTT message delay:100``" - " Name"," :red:`Internal`"," Set the name of the unit diff --git a/docs/source/Plugin/P036.rst b/docs/source/Plugin/P036.rst index 14f796534..2f6cf8654 100644 --- a/docs/source/Plugin/P036.rst +++ b/docs/source/Plugin/P036.rst @@ -35,6 +35,8 @@ Please note that scrolling may need more resources of the ESP, which can have an The plugin allows for a header and footer line, which may show some user selectable information. +Checkbox 'Wake display on receiving text' (default: on) allows to not wake up the display when a text is sent from a remote source, and Display Timeout is set. + All user defined texts may contain references to system variables or task values which will be interpreted when displayed on screen. For example: ``[bme#T#D2.1] {D}C [bme#H]%`` diff --git a/platformio_core_defs.ini b/platformio_core_defs.ini index ade9c4545..bdacd2fdd 100644 --- a/platformio_core_defs.ini +++ b/platformio_core_defs.ini @@ -46,7 +46,7 @@ build_flags = -D BUILD_GIT='"${sysenv.TRAVIS_TAG}"' -DVTABLES_IN_FLASH -fno-exceptions -lstdc++ - -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY_LOW_FLASH + -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH -DPUYA_SUPPORT=1 -DCORE_POST_2_5_0 @@ -129,7 +129,7 @@ platform = espressif8266@2.4.0 platform_packages = framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git#2.6.3 build_flags = ${esp82xx_2_6_x.build_flags} - -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_191122 + -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 [core_2_6_3_sdk3] platform = espressif8266@2.4.0 diff --git a/platformio_esp82xx_base.ini b/platformio_esp82xx_base.ini index d585c96bf..19812ef1b 100644 --- a/platformio_esp82xx_base.ini +++ b/platformio_esp82xx_base.ini @@ -118,9 +118,11 @@ build_flags = ${ir.build_flags} -DPLUGIN_BUILD_IR_EXTENDED_NO_RX extends = esp82xx_common board_build.flash_mode = dout board_upload.maximum_size = 786432 -build_flags = -Wl,-Tesp8266.flash.1m128.ld - -DSIZE_1M +board_build.ldscript = eagle.flash.1m128.ld +build_flags = -DSIZE_1M -DBUILD_NO_DEBUG + -Os + -s ${esp82xx_common.build_flags} [esp8266_1M] @@ -137,7 +139,7 @@ build_flags = ${esp8266_1M.build_flags} -DESP8285 ; Minimal build size for OTA ; ; ********************************************************************* [esp82xx_1M_OTA] -extends = esp82xx_common +extends = esp82xx_1M board_build.flash_mode = dout board_upload.maximum_size = 616448 build_flags = ${esp82xx_1M.build_flags} -DPLUGIN_BUILD_MINIMAL_OTA @@ -162,24 +164,24 @@ extends = esp82xx_common board = esp12e board_build.flash_mode = dout board_upload.maximum_size = 1044464 -build_flags = -Wl,-Tesp8266.flash.2m256.ld - ${esp82xx_common.build_flags} +board_build.ldscript = eagle.flash.2m256.ld +build_flags = ${esp82xx_common.build_flags} [espWroom2M] extends = esp82xx_common board = esp12e board_build.flash_mode = dout board_upload.maximum_size = 1044464 -build_flags = -Wl,-Tesp8266.flash.2m.ld - ${esp82xx_common.build_flags} +board_build.ldscript = eagle.flash.2m.ld +build_flags = ${esp82xx_common.build_flags} [espWroom2M256] extends = esp82xx_common board_build.flash_mode = dout board_upload.maximum_size = 1044464 board = esp_wroom_02 -build_flags = -Wl,-Tesp8266.flash.2m256.ld - ${esp82xx_common.build_flags} +board_build.ldscript = eagle.flash.2m256.ld +build_flags = ${esp82xx_common.build_flags} ;;; 4MB flash nodes ************************************************** @@ -191,16 +193,16 @@ extends = esp82xx_common board = esp12e board_build.flash_mode = dout board_upload.maximum_size = 1044464 -build_flags = -Wl,-Tesp8266.flash.4m1m.ld - ${esp82xx_common.build_flags} +board_build.ldscript = eagle.flash.4m1m.ld +build_flags = ${esp82xx_common.build_flags} [esp8266_4M2M] extends = esp82xx_common board = esp12e board_build.flash_mode = dout board_upload.maximum_size = 1044464 -build_flags = -Wl,-Tesp8266.flash.4m2m.ld - ${esp82xx_common.build_flags} +board_build.ldscript = eagle.flash.4m2m.ld +build_flags = ${esp82xx_common.build_flags} @@ -217,7 +219,7 @@ extends = esp82xx_common board = esp12e board_build.flash_mode = dout board_upload.maximum_size = 1044464 -build_flags = -Wl,-Tesp8266.flash.16m14m.ld - -DSPIFFS_MAX_OPEN_FILES=20 +board_build.ldscript = eagle.flash.16m14m.ld +build_flags = -DSPIFFS_MAX_OPEN_FILES=20 ${esp82xx_common.build_flags} diff --git a/src/Command.ino b/src/Command.ino index 6869e3cd0..d43feabfd 100644 --- a/src/Command.ino +++ b/src/Command.ino @@ -94,6 +94,24 @@ bool checkNrArguments(const char *cmd, const char *Line, int nrArguments) { return true; } +typedef String (*command_function)(struct EventStruct *, const char *); +bool do_command_case(const String& cmd_lc, const char *cmd, struct EventStruct *event, const char *line, String& status, const String& cmd_test, command_function pFunc, int nrArguments, bool& retval); + +bool do_command_case(const String& cmd_lc, const char *cmd, struct EventStruct *event, const char *line, String& status, const String& cmd_test, command_function pFunc, int nrArguments, bool& retval) +{ + if (cmd_lc.equals(cmd_test)) { + if (!checkNrArguments(cmd, line, nrArguments)) { + status = return_incorrect_nr_arguments(); + retval = false; + } else { + status = pFunc(event, line); + retval = true; + } + return true; // Command is handled + } + return false; +} + /*********************************************************************************************\ * Registers command \*********************************************************************************************/ @@ -103,13 +121,10 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch cmd_lc = cmd; cmd_lc.toLowerCase(); + bool retval; // Simple macro to match command to function call. #define COMMAND_CASE(S, C, NARGS) \ - if (strcmp_P(cmd_lc.c_str(), \ - PSTR(S)) == 0) \ - { if (!checkNrArguments(cmd, line, NARGS)) { \ - status = return_incorrect_nr_arguments(); return false;} \ - else status = C (event, line); return true;} + if (do_command_case(cmd_lc, cmd, event, line, status, F(S), &C, NARGS, retval)) { return retval; } // FIXME TD-er: Should we execute command when number of arguments is wrong? @@ -189,10 +204,6 @@ bool executeInternalCommand(const char *cmd, struct EventStruct *event, const ch COMMAND_CASE( "meminfo", Command_MemInfo, 0); // Diagnostic.h COMMAND_CASE( "meminfodetail", Command_MemInfo_detail, 0); // Diagnostic.h #endif -#ifdef USES_MQTT - COMMAND_CASE( "messagedelay", Command_MQTT_messageDelay, 1); // MQTT.h - COMMAND_CASE("mqttretainflag", Command_MQTT_Retain, 1); // MQTT.h -#endif // USES_MQTT break; } case 'n': { diff --git a/src/Controller.ino b/src/Controller.ino index 478311725..652746f39 100644 --- a/src/Controller.ino +++ b/src/Controller.ino @@ -1,14 +1,16 @@ -#include "src/DataStructs/ESPEasy_EventStruct.h" -#include "src/Globals/Device.h" -#include "src/Globals/Plugins.h" -#include "src/Globals/Protocol.h" -#include "src/Globals/CPlugins.h" #include "ESPEasy_common.h" #include "ESPEasy_fdwdecl.h" #include "ESPEasy_plugindefs.h" +#include "src/DataStructs/ControllerSettingsStruct.h" +#include "src/DataStructs/ESPEasy_EventStruct.h" +#include "src/Globals/CPlugins.h" +#include "src/Globals/Device.h" +#include "src/Globals/MQTT.h" +#include "src/Globals/Plugins.h" +#include "src/Globals/Protocol.h" +#include "_CPlugin_Helper.h" // ******************************************************************************** - // Interface for Sending to Controllers // ******************************************************************************** void sendData(struct EventStruct *event) @@ -25,29 +27,6 @@ void sendData(struct EventStruct *event) SendValueLogger(event->TaskIndex); } - // if (!Settings.TaskDeviceSendData[event->TaskIndex]) - // return false; - - /* - // Disabed for now, using buffers at controller side. - if (Settings.MessageDelay != 0) - { - const long dif = timePassedSince(lastSend); - if (dif > 0 && dif < static_cast(Settings.MessageDelay)) - { - uint16_t delayms = Settings.MessageDelay - dif; - //this is logged nowhere else, so might as well disable it here also: - // addLog(LOG_LEVEL_DEBUG_MORE, String(F("CTRL : Message delay (ms): "))+delayms); - - delayBackground(delayms); - - // unsigned long timer = millis() + delayms; - // while (!timeOutReached(timer)) - // backgroundtasks(); - } - } - */ - LoadTaskSettings(event->TaskIndex); // could have changed during background tasks. for (controllerIndex_t x = 0; x < CONTROLLER_MAX; x++) @@ -196,26 +175,7 @@ bool MQTTConnect(controllerIndex_t controller_idx) MQTTclient.setCallback(callback); // MQTT needs a unique clientname to subscribe to broker - String clientid; - - if (Settings.MQTTUseUnitNameAsClientId) { - clientid = Settings.getHostname(); - } - else { - clientid = F("ESPClient_"); - clientid += WiFi.macAddress(); - } - clientid.replace(' ', '_'); // Make sure no spaces are present in the client ID - - if ((wifi_reconnects >= 1) && Settings.uniqueMQTTclientIdReconnect()) { - // Work-around for 'lost connections' to the MQTT broker. - // If the broker thinks the connection is still alive, a reconnect from the - // client will be refused. - // To overcome this issue, append the number of reconnects to the client ID to - // make it different from the previous one. - clientid += '_'; - clientid += wifi_reconnects; - } + String clientid = getMQTTclientID(ControllerSettings); String LWTTopic = ControllerSettings.MQTTLwtTopic; @@ -246,11 +206,11 @@ bool MQTTConnect(controllerIndex_t controller_idx) bool willRetain = ControllerSettings.mqtt_willRetain() && ControllerSettings.mqtt_sendLWT(); bool cleanSession = ControllerSettings.mqtt_cleanSession(); // As suggested here: https://github.com/knolleary/pubsubclient/issues/458#issuecomment-493875150 - if ((SecuritySettings.ControllerUser[controller_idx] != 0) && (SecuritySettings.ControllerPassword[controller_idx] != 0)) { + if (hasControllerCredentialsSet(controller_idx, ControllerSettings)) { MQTTresult = MQTTclient.connect(clientid.c_str(), - SecuritySettings.ControllerUser[controller_idx], - SecuritySettings.ControllerPassword[controller_idx], + getControllerUser(controller_idx, ControllerSettings).c_str(), + getControllerPass(controller_idx, ControllerSettings).c_str(), ControllerSettings.mqtt_sendLWT() ? LWTTopic.c_str() : nullptr, willQos, willRetain, @@ -299,6 +259,27 @@ bool MQTTConnect(controllerIndex_t controller_idx) return false; } +String getMQTTclientID(const ControllerSettingsStruct& ControllerSettings) { + String clientid = ControllerSettings.ClientID; + if (clientid.length() == 0) { + // Try to generate some default + clientid = F(CONTROLLER_DEFAULT_CLIENTID); + } + parseSystemVariables(clientid, false); + clientid.replace(' ', '_'); // Make sure no spaces are present in the client ID + + if ((wifi_reconnects >= 1) && ControllerSettings.mqtt_uniqueMQTTclientIdReconnect()) { + // Work-around for 'lost connections' to the MQTT broker. + // If the broker thinks the connection is still alive, a reconnect from the + // client will be refused. + // To overcome this issue, append the number of reconnects to the client ID to + // make it different from the previous one. + clientid += '_'; + clientid += wifi_reconnects; + } + return clientid; +} + /*********************************************************************************************\ * Check connection MQTT message broker \*********************************************************************************************/ @@ -432,7 +413,7 @@ void MQTTStatus(const String& status) String pubname = ControllerSettings.Subscribe; pubname.replace(F("/#"), F("/status")); parseSystemVariables(pubname, false); - MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(), Settings.MQTTRetainFlag); + MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(), ControllerSettings.mqtt_retainFlag()); } } #endif //USES_MQTT diff --git a/src/Custom-sample.h b/src/Custom-sample.h index 2319d686f..ce9952a57 100644 --- a/src/Custom-sample.h +++ b/src/Custom-sample.h @@ -79,6 +79,7 @@ #define DEFAULT_SERVER "192.168.0.8" // Enter your Server IP address #define DEFAULT_SERVER_HOST "" // Server hostname #define DEFAULT_SERVER_USEDNS false // true: Use hostname. false: use IP +#define DEFAULT_USE_EXTD_CONTROLLER_CREDENTIALS false // true: Allow longer user credentials for controllers #define DEFAULT_PORT 8080 // Enter your Server port value diff --git a/src/ESPEasyRTC.ino b/src/ESPEasyRTC.ino index 3ec6a937a..9326a3a21 100644 --- a/src/ESPEasyRTC.ino +++ b/src/ESPEasyRTC.ino @@ -213,7 +213,7 @@ struct RTC_cache_handler_struct } if (fname.length() == 0) { return false; } - fp = tryOpenFile(fname.c_str(), "r"); + fp = tryOpenFile(fname, "r"); } if (!fp) { return false; } @@ -529,7 +529,7 @@ private: } String fname = createCacheFilename(RTC_cache.writeFileNr); - fw = tryOpenFile(fname.c_str(), "a+"); + fw = tryOpenFile(fname, "a+"); if (!fw) { #ifdef RTC_STRUCT_DEBUG diff --git a/src/ESPEasyStorage.ino b/src/ESPEasyStorage.ino index 55a66ba84..700e60898 100644 --- a/src/ESPEasyStorage.ino +++ b/src/ESPEasyStorage.ino @@ -141,7 +141,7 @@ String BuildFixes() Settings.UseRTOSMultitasking = false; Settings.Pin_Reset = -1; Settings.SyslogFacility = DEFAULT_SYSLOG_FACILITY; - Settings.MQTTUseUnitNameAsClientId = DEFAULT_MQTT_USE_UNITNAME_AS_CLIENTID; + Settings.MQTTUseUnitNameAsClientId_unused = DEFAULT_MQTT_USE_UNITNAME_AS_CLIENTID; Settings.StructSize = sizeof(Settings); } @@ -152,6 +152,32 @@ String BuildFixes() if (Settings.Build < 20105) { Settings.I2C_clockSpeed = 400000; } + if (Settings.Build <= 20106) { + // ClientID is now defined in the controller settings. + #ifdef USES_MQTT + controllerIndex_t controller_idx = firstEnabledMQTT_ControllerIndex(); + if (validControllerIndex(controller_idx)) { + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(controller_idx, ControllerSettings); + + String clientid; + if (Settings.MQTTUseUnitNameAsClientId_unused) { + clientid = F("%sysname%"); + if (Settings.appendUnitToHostname()) { + clientid += F("_%unit%"); + } + } + else { + clientid = F("ESPClient_%mac%"); + } + safe_strncpy(ControllerSettings.ClientID, clientid, sizeof(ControllerSettings.ClientID)); + + ControllerSettings.mqtt_uniqueMQTTclientIdReconnect(Settings.uniqueMQTTclientIdReconnect_unused()); + ControllerSettings.mqtt_retainFlag(Settings.MQTTRetainFlag_unused); + SaveControllerSettings(controller_idx, ControllerSettings); + } + #endif // USES_MQTT + } Settings.Build = BUILD; return SaveSettings(); @@ -187,7 +213,7 @@ void fileSystemCheck() } #endif // if defined(ESP8266) - fs::File f = tryOpenFile(FILE_CONFIG, "r"); + fs::File f = tryOpenFile(SettingsType::getSettingsFileName(SettingsType::BasicSettings_Type).c_str(), "r"); if (!f) { @@ -253,7 +279,7 @@ String SaveSettings(void) memcpy(Settings.md5, tmp_md5, 16); */ Settings.validate(); - err = SaveToFile((char *)FILE_CONFIG, 0, (byte *)&Settings, sizeof(Settings)); + err = SaveToFile(SettingsType::getSettingsFileName(SettingsType::BasicSettings_Type).c_str(), 0, (byte *)&Settings, sizeof(Settings)); if (err.length()) { return err; @@ -283,6 +309,7 @@ String SaveSettings(void) wifiConnectAttemptNeeded = true; } } + ExtendedControllerCredentials.save(); afterloadSettings(); return err; } @@ -316,7 +343,7 @@ String LoadSettings() uint8_t calculatedMd5[16]; MD5Builder md5; - err = LoadFromFile((char *)FILE_CONFIG, 0, (byte *)&Settings, sizeof(SettingsStruct)); + err = LoadFromFile(SettingsType::getSettingsFileName(SettingsType::BasicSettings_Type).c_str(), 0, (byte *)&Settings, sizeof(SettingsStruct)); if (err.length()) { return err; @@ -359,6 +386,8 @@ String LoadSettings() addLog(LOG_LEVEL_ERROR, F("CRC : SecuritySettings CRC ...FAIL")); } + ExtendedControllerCredentials.load(); + // setupStaticIPconfig(); // FIXME TD-er: Must check if static/dynamic IP was changed and trigger a reconnect? Or is a reboot better when changing those settings? afterloadSettings(); @@ -416,203 +445,97 @@ byte disableNotification(byte bootFailedCount) { #include "src/DataStructs/StorageLayout.h" -/********************************************************************************************\ - Offsets in settings files - \*********************************************************************************************/ -bool getSettingsParameters(SettingsType settingsType, int index, int& max_index, int& offset, int& max_size, int& struct_size) { - // The defined offsets should be used with () just in case they are the result of a formula in the defines. - struct_size = 0; - switch (settingsType) { - case BasicSettings_Type: - { - max_index = 1; - offset = 0; - max_size = (DAT_BASIC_SETTINGS_SIZE); - struct_size = sizeof(SettingsStruct); - break; - } - case TaskSettings_Type: - { - max_index = TASKS_MAX; - offset = (DAT_OFFSET_TASKS) + (index * (DAT_TASKS_DISTANCE)); - max_size = DAT_TASKS_SIZE; - struct_size = sizeof(ExtraTaskSettingsStruct); - break; - } - case CustomTaskSettings_Type: - { - getSettingsParameters(TaskSettings_Type, index, max_index, offset, max_size, struct_size); - offset += (DAT_TASKS_CUSTOM_OFFSET); - max_size = DAT_TASKS_CUSTOM_SIZE; - break; - - // struct_size may differ. - } - case ControllerSettings_Type: - { - max_index = CONTROLLER_MAX; - offset = (DAT_OFFSET_CONTROLLER) + (index * (DAT_CONTROLLER_SIZE)); - max_size = DAT_CONTROLLER_SIZE; - struct_size = sizeof(ControllerSettingsStruct); - break; - } - case CustomControllerSettings_Type: - { - max_index = CONTROLLER_MAX; - offset = (DAT_OFFSET_CUSTOM_CONTROLLER) + (index * (DAT_CUSTOM_CONTROLLER_SIZE)); - max_size = DAT_CUSTOM_CONTROLLER_SIZE; - - // struct_size may differ. - } break; - case NotificationSettings_Type: - { - max_index = NOTIFICATION_MAX; - offset = index * (DAT_NOTIFICATION_SIZE); - max_size = DAT_NOTIFICATION_SIZE; - struct_size = sizeof(NotificationSettingsStruct); - break; - } - default: - { - max_index = -1; - offset = -1; - return false; - } - } - return index >= 0 && index < max_index; -} - -int getMaxFilePos(SettingsType settingsType) { - int max_index, offset, max_size; - int struct_size = 0; - - getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); - getSettingsParameters(settingsType, max_index - 1, offset, max_size); - return offset + max_size - 1; -} - -int getFileSize(SettingsType settingsType) { - if (settingsType == NotificationSettings_Type) { - return getMaxFilePos(settingsType); - } - - int max_file_pos = 0; - - for (int st = 0; st < SettingsType_MAX; ++st) { - int filePos = getMaxFilePos(static_cast(st)); - - if (filePos > max_file_pos) { - max_file_pos = filePos; - } - } - return max_file_pos; -} - -bool getAndLogSettingsParameters(bool read, SettingsType settingsType, int index, int& offset, int& max_size) { +bool getAndLogSettingsParameters(bool read, SettingsType::Enum settingsType, int index, int& offset, int& max_size) { #ifndef BUILD_NO_DEBUG if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) { String log = read ? F("Read") : F("Write"); log += F(" settings: "); - log += getSettingsTypeString(settingsType); + log += SettingsType::getSettingsTypeString(settingsType); log += F(" index: "); log += index; addLog(LOG_LEVEL_DEBUG_DEV, log); } #endif // ifndef BUILD_NO_DEBUG - return getSettingsParameters(settingsType, index, offset, max_size); + return SettingsType::getSettingsParameters(settingsType, index, offset, max_size); } -bool getSettingsParameters(SettingsType settingsType, int index, int& offset, int& max_size) { - int max_index = -1; - int struct_size; - - if (!getSettingsParameters(settingsType, index, max_index, offset, max_size, struct_size)) { - return false; - } - - if ((index >= 0) && (index < max_index)) { return true; } - offset = -1; - return false; -} /********************************************************************************************\ - Save Task settings to SPIFFS + Load array of Strings from Custom settings + Use maxStringLength = 0 to optimize for size (strings will be concatenated) \*********************************************************************************************/ -String SaveTaskSettings(taskIndex_t TaskIndex) +String LoadStringArray(SettingsType::Enum settingsType, int index, String strings[], uint16_t nrStrings, uint16_t maxStringLength) { - checkRAM(F("SaveTaskSettings")); - - if (ExtraTaskSettings.TaskIndex != TaskIndex) { - return F("SaveTaskSettings taskIndex does not match"); - } - String err = SaveToFile(TaskSettings_Type, - TaskIndex, - (char *)FILE_CONFIG, - (byte *)&ExtraTaskSettings, - sizeof(struct ExtraTaskSettingsStruct)); - - if (err.length() == 0) { - err = checkTaskSettings(TaskIndex); - } - return err; -} - -/********************************************************************************************\ - Load Task settings from SPIFFS - \*********************************************************************************************/ -String LoadTaskSettings(taskIndex_t TaskIndex) -{ - if (ExtraTaskSettings.TaskIndex == TaskIndex) { - return String(); // already loaded + int offset, max_size; + if (!SettingsType::getSettingsParameters(settingsType, index, offset, max_size)) + { + return F("Invalid index for custom settings"); } - if (!validTaskIndex(TaskIndex)) { - return String(); // Un-initialized task index. + const uint16_t bufferSize = 128; + + // FIXME TD-er: For now stack allocated, may need to be heap allocated? + if (maxStringLength >= bufferSize) { return F("Max 128 chars allowed"); } + char buffer[bufferSize]; + + String result; + uint16_t readPos = 0; + uint16_t nextStringPos = 0; + uint16_t stringCount = 0; + String tmpString; + tmpString.reserve(bufferSize); + + while (stringCount < nrStrings && readPos < max_size) { + result += LoadFromFile(settingsType, + index, + (byte *)&buffer, + bufferSize, + readPos); + + for (int i = 0; i < bufferSize && stringCount < nrStrings; ++i) { + uint16_t curPos = readPos + i; + + if (curPos >= nextStringPos) { + if (buffer[i] == 0) { + if (maxStringLength != 0) { + // Specific string length, so we have to set the next string position. + nextStringPos += maxStringLength; + } + strings[stringCount] = tmpString; + tmpString = ""; + tmpString.reserve(bufferSize); + ++stringCount; + } else { + tmpString += buffer[i]; + } + } + } + readPos += bufferSize; } - checkRAM(F("LoadTaskSettings")); - START_TIMER - ExtraTaskSettings.clear(); - String result = ""; - result = - LoadFromFile(TaskSettings_Type, TaskIndex, (char *)FILE_CONFIG, (byte *)&ExtraTaskSettings, sizeof(struct ExtraTaskSettingsStruct)); - - // After loading, some settings may need patching. - ExtraTaskSettings.TaskIndex = TaskIndex; // Needed when an empty task was requested - - if (ExtraTaskSettings.TaskDeviceValueNames[0][0] == 0) { - // if field set empty, reload defaults - struct EventStruct TempEvent; - TempEvent.TaskIndex = TaskIndex; - String tmp; - - // the plugin call should populate ExtraTaskSettings with its default values. - PluginCall(PLUGIN_GET_DEVICEVALUENAMES, &TempEvent, tmp); + if ((tmpString.length() != 0) && (stringCount < nrStrings)) { + result += F("Incomplete custom settings for index "); + result += (index + 1); + strings[stringCount] = tmpString; } - ExtraTaskSettings.validate(); - STOP_TIMER(LOAD_TASK_SETTINGS); - return result; } -/********************************************************************************************\ - Save Custom Task settings to SPIFFS - \*********************************************************************************************/ -String SaveCustomTaskSettings(taskIndex_t TaskIndex, byte *memAddress, int datasize) -{ - checkRAM(F("SaveCustomTaskSettings")); - return SaveToFile(CustomTaskSettings_Type, TaskIndex, (char *)FILE_CONFIG, memAddress, datasize); -} /********************************************************************************************\ - Save array of Strings to Custom Task settings + Save array of Strings from Custom settings Use maxStringLength = 0 to optimize for size (strings will be concatenated) \*********************************************************************************************/ -String SaveCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t nrStrings, uint16_t maxStringLength) +String SaveStringArray(SettingsType::Enum settingsType, int index, const String strings[], uint16_t nrStrings, uint16_t maxStringLength) { - checkRAM(F("SaveCustomTaskSettings")); + int offset, max_size; + if (!SettingsType::getSettingsParameters(settingsType, index, offset, max_size)) + { + return F("Invalid index for custom settings"); + } + const uint16_t bufferSize = 128; // FIXME TD-er: For now stack allocated, may need to be heap allocated? @@ -634,7 +557,7 @@ String SaveCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t } } - while (stringCount < nrStrings && writePos < DAT_TASKS_CUSTOM_SIZE) { + while (stringCount < nrStrings && writePos < max_size) { ZERO_FILL(buffer); for (int i = 0; i < bufferSize && stringCount < nrStrings; ++i) { @@ -674,16 +597,98 @@ String SaveCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t if (RTC.flashDayCounter > 0) { RTC.flashDayCounter--; } - result += SaveToFile(CustomTaskSettings_Type, TaskIndex, (char *)FILE_CONFIG, &(buffer[0]), bufferSize, writePos); + result += SaveToFile(settingsType, index, &(buffer[0]), bufferSize, writePos); writePos += bufferSize; } - if ((writePos >= DAT_TASKS_CUSTOM_SIZE) && (stringCount < nrStrings)) { - result += F("Error: Not all strings fit in custom task settings."); + if ((writePos >= max_size) && (stringCount < nrStrings)) { + result += F("Error: Not all strings fit in custom settings."); } return result; } + + +/********************************************************************************************\ + Save Task settings to SPIFFS + \*********************************************************************************************/ +String SaveTaskSettings(taskIndex_t TaskIndex) +{ + checkRAM(F("SaveTaskSettings")); + + if (ExtraTaskSettings.TaskIndex != TaskIndex) { + return F("SaveTaskSettings taskIndex does not match"); + } + String err = SaveToFile(SettingsType::TaskSettings_Type, + TaskIndex, + (byte *)&ExtraTaskSettings, + sizeof(struct ExtraTaskSettingsStruct)); + + if (err.length() == 0) { + err = checkTaskSettings(TaskIndex); + } + return err; +} + +/********************************************************************************************\ + Load Task settings from SPIFFS + \*********************************************************************************************/ +String LoadTaskSettings(taskIndex_t TaskIndex) +{ + if (ExtraTaskSettings.TaskIndex == TaskIndex) { + return String(); // already loaded + } + + if (!validTaskIndex(TaskIndex)) { + return String(); // Un-initialized task index. + } + checkRAM(F("LoadTaskSettings")); + + START_TIMER + ExtraTaskSettings.clear(); + String result = ""; + result = + LoadFromFile(SettingsType::TaskSettings_Type, TaskIndex, (byte *)&ExtraTaskSettings, sizeof(struct ExtraTaskSettingsStruct)); + + // After loading, some settings may need patching. + ExtraTaskSettings.TaskIndex = TaskIndex; // Needed when an empty task was requested + + if (ExtraTaskSettings.TaskDeviceValueNames[0][0] == 0) { + // if field set empty, reload defaults + struct EventStruct TempEvent; + TempEvent.TaskIndex = TaskIndex; + String tmp; + + // the plugin call should populate ExtraTaskSettings with its default values. + PluginCall(PLUGIN_GET_DEVICEVALUENAMES, &TempEvent, tmp); + } + ExtraTaskSettings.validate(); + STOP_TIMER(LOAD_TASK_SETTINGS); + + return result; +} + +/********************************************************************************************\ + Save Custom Task settings to SPIFFS + \*********************************************************************************************/ +String SaveCustomTaskSettings(taskIndex_t TaskIndex, byte *memAddress, int datasize) +{ + checkRAM(F("SaveCustomTaskSettings")); + return SaveToFile(SettingsType::CustomTaskSettings_Type, TaskIndex, memAddress, datasize); +} + +/********************************************************************************************\ + Save array of Strings to Custom Task settings + Use maxStringLength = 0 to optimize for size (strings will be concatenated) + \*********************************************************************************************/ +String SaveCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t nrStrings, uint16_t maxStringLength) +{ + checkRAM(F("SaveCustomTaskSettings")); + return SaveStringArray( + SettingsType::CustomTaskSettings_Type, TaskIndex, + strings, nrStrings, maxStringLength); +} + String getCustomTaskSettingsError(byte varNr) { String error = F("Error: Text too long for line "); @@ -698,7 +703,7 @@ String getCustomTaskSettingsError(byte varNr) { String ClearCustomTaskSettings(taskIndex_t TaskIndex) { // addLog(LOG_LEVEL_DEBUG, F("Clearing custom task settings")); - return ClearInFile(CustomTaskSettings_Type, TaskIndex, (char *)FILE_CONFIG); + return ClearInFile(SettingsType::CustomTaskSettings_Type, TaskIndex); } /********************************************************************************************\ @@ -708,7 +713,7 @@ String LoadCustomTaskSettings(taskIndex_t TaskIndex, byte *memAddress, int datas { START_TIMER; checkRAM(F("LoadCustomTaskSettings")); - String result = LoadFromFile(CustomTaskSettings_Type, TaskIndex, (char *)FILE_CONFIG, memAddress, datasize); + String result = LoadFromFile(SettingsType::CustomTaskSettings_Type, TaskIndex, memAddress, datasize); STOP_TIMER(LOAD_CUSTOM_TASK_STATS); return result; } @@ -721,54 +726,9 @@ String LoadCustomTaskSettings(taskIndex_t TaskIndex, String strings[], uint16_t { START_TIMER; checkRAM(F("LoadCustomTaskSettings")); - - const uint16_t bufferSize = 128; - - // FIXME TD-er: For now stack allocated, may need to be heap allocated? - if (maxStringLength >= bufferSize) { return F("Max 128 chars allowed"); } - char buffer[bufferSize]; - - String result; - uint16_t readPos = 0; - uint16_t nextStringPos = 0; - uint16_t stringCount = 0; - String tmpString; - tmpString.reserve(bufferSize); - - while (stringCount < nrStrings && readPos < DAT_TASKS_CUSTOM_SIZE) { - result += LoadFromFile(CustomTaskSettings_Type, + String result = LoadStringArray(SettingsType::CustomTaskSettings_Type, TaskIndex, - (char *)FILE_CONFIG, - (byte *)&buffer, - bufferSize, - readPos); - - for (int i = 0; i < bufferSize && stringCount < nrStrings; ++i) { - uint16_t curPos = readPos + i; - - if (curPos >= nextStringPos) { - if (buffer[i] == 0) { - if (maxStringLength != 0) { - // Specific string length, so we have to set the next string position. - nextStringPos += maxStringLength; - } - strings[stringCount] = tmpString; - tmpString = ""; - tmpString.reserve(bufferSize); - ++stringCount; - } else { - tmpString += buffer[i]; - } - } - } - readPos += bufferSize; - } - - if ((tmpString.length() != 0) && (stringCount < nrStrings)) { - result += F("Incomplete custom settings for task "); - result += (TaskIndex + 1); - strings[stringCount] = tmpString; - } + strings, nrStrings, maxStringLength); STOP_TIMER(LOAD_CUSTOM_TASK_STATS); return result; } @@ -780,8 +740,8 @@ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti { checkRAM(F("SaveControllerSettings")); controller_settings.validate(); // Make sure the saved controller settings have proper values. - return SaveToFile(ControllerSettings_Type, ControllerIndex, - (char *)FILE_CONFIG, (byte *)&controller_settings, sizeof(controller_settings)); + return SaveToFile(SettingsType::ControllerSettings_Type, ControllerIndex, + (byte *)&controller_settings, sizeof(controller_settings)); } /********************************************************************************************\ @@ -790,8 +750,8 @@ String SaveControllerSettings(controllerIndex_t ControllerIndex, ControllerSetti String LoadControllerSettings(controllerIndex_t ControllerIndex, ControllerSettingsStruct& controller_settings) { checkRAM(F("LoadControllerSettings")); String result = - LoadFromFile(ControllerSettings_Type, ControllerIndex, - (char *)FILE_CONFIG, (byte *)&controller_settings, sizeof(controller_settings)); + LoadFromFile(SettingsType::ControllerSettings_Type, ControllerIndex, + (byte *)&controller_settings, sizeof(controller_settings)); controller_settings.validate(); // Make sure the loaded controller settings have proper values. return result; } @@ -804,7 +764,7 @@ String ClearCustomControllerSettings(controllerIndex_t ControllerIndex) checkRAM(F("ClearCustomControllerSettings")); // addLog(LOG_LEVEL_DEBUG, F("Clearing custom controller settings")); - return ClearInFile(CustomControllerSettings_Type, ControllerIndex, (char *)FILE_CONFIG); + return ClearInFile(SettingsType::CustomControllerSettings_Type, ControllerIndex); } /********************************************************************************************\ @@ -813,7 +773,7 @@ String ClearCustomControllerSettings(controllerIndex_t ControllerIndex) String SaveCustomControllerSettings(controllerIndex_t ControllerIndex, byte *memAddress, int datasize) { checkRAM(F("SaveCustomControllerSettings")); - return SaveToFile(CustomControllerSettings_Type, ControllerIndex, (char *)FILE_CONFIG, memAddress, datasize); + return SaveToFile(SettingsType::CustomControllerSettings_Type, ControllerIndex, memAddress, datasize); } /********************************************************************************************\ @@ -822,7 +782,7 @@ String SaveCustomControllerSettings(controllerIndex_t ControllerIndex, byte *mem String LoadCustomControllerSettings(controllerIndex_t ControllerIndex, byte *memAddress, int datasize) { checkRAM(F("LoadCustomControllerSettings")); - return LoadFromFile(CustomControllerSettings_Type, ControllerIndex, (char *)FILE_CONFIG, memAddress, datasize); + return LoadFromFile(SettingsType::CustomControllerSettings_Type, ControllerIndex, memAddress, datasize); } /********************************************************************************************\ @@ -831,7 +791,7 @@ String LoadCustomControllerSettings(controllerIndex_t ControllerIndex, byte *mem String SaveNotificationSettings(int NotificationIndex, byte *memAddress, int datasize) { checkRAM(F("SaveNotificationSettings")); - return SaveToFile(NotificationSettings_Type, NotificationIndex, (char *)FILE_NOTIFICATION, memAddress, datasize); + return SaveToFile(SettingsType::NotificationSettings_Type, NotificationIndex, memAddress, datasize); } /********************************************************************************************\ @@ -840,13 +800,13 @@ String SaveNotificationSettings(int NotificationIndex, byte *memAddress, int dat String LoadNotificationSettings(int NotificationIndex, byte *memAddress, int datasize) { checkRAM(F("LoadNotificationSettings")); - return LoadFromFile(NotificationSettings_Type, NotificationIndex, (char *)FILE_NOTIFICATION, memAddress, datasize); + return LoadFromFile(SettingsType::NotificationSettings_Type, NotificationIndex, memAddress, datasize); } /********************************************************************************************\ Init a file with zeros on SPIFFS \*********************************************************************************************/ -String InitFile(const char *fname, int datasize) +String InitFile(const String& fname, int datasize) { checkRAM(F("InitFile")); FLASH_GUARD(); @@ -854,13 +814,13 @@ String InitFile(const char *fname, int datasize) fs::File f = tryOpenFile(fname, "w"); if (f) { - SPIFFS_CHECK(f, fname); + SPIFFS_CHECK(f, fname.c_str()); for (int x = 0; x < datasize; x++) { // See https://github.com/esp8266/Arduino/commit/b1da9eda467cc935307d553692fdde2e670db258#r32622483 uint8_t zero_value = 0; - SPIFFS_CHECK(f.write(&zero_value, 1), fname); + SPIFFS_CHECK(f.write(&zero_value, 1), fname.c_str()); } f.close(); } @@ -965,7 +925,7 @@ String doSaveToFile(const char *fname, int index, const byte *memAddress, int da /********************************************************************************************\ Clear a certain area in a file (set to 0) \*********************************************************************************************/ -String ClearInFile(char *fname, int index, int datasize) +String ClearInFile(const char *fname, int index, int datasize) { if (index < 0) { String log = F("ClearInFile: "); @@ -1007,7 +967,7 @@ String ClearInFile(char *fname, int index, int datasize) /********************************************************************************************\ Load data from config file on SPIFFS \*********************************************************************************************/ -String LoadFromFile(char *fname, int offset, byte *memAddress, int datasize) +String LoadFromFile(const char *fname, int offset, byte *memAddress, int datasize) { if (offset < 0) { String log = F("LoadFromFile: "); @@ -1035,23 +995,23 @@ String LoadFromFile(char *fname, int offset, byte *memAddress, int datasize) /********************************************************************************************\ Wrapper functions to handle errors in accessing settings \*********************************************************************************************/ -String getSettingsFileIndexRangeError(bool read, SettingsType settingsType, int index) { - if (settingsType >= SettingsType_MAX) { +String getSettingsFileIndexRangeError(bool read, SettingsType::Enum settingsType, int index) { + if (settingsType >= SettingsType::SettingsType_MAX) { String error = F("Unknown settingsType: "); error += static_cast(settingsType); return error; } String error = read ? F("Load") : F("Save"); - error += getSettingsTypeString(settingsType); + error += SettingsType::getSettingsTypeString(settingsType); error += F(" index out of range: "); error += index; return error; } -String getSettingsFileDatasizeError(bool read, SettingsType settingsType, int index, int datasize, int max_size) { +String getSettingsFileDatasizeError(bool read, SettingsType::Enum settingsType, int index, int datasize, int max_size) { String error = read ? F("Load") : F("Save"); - error += getSettingsTypeString(settingsType); + error += SettingsType::getSettingsTypeString(settingsType); error += '('; error += index; error += F(") datasize("); @@ -1062,7 +1022,7 @@ String getSettingsFileDatasizeError(bool read, SettingsType settingsType, int in return error; } -String LoadFromFile(SettingsType settingsType, int index, char *fname, byte *memAddress, int datasize, int offset_in_block) { +String LoadFromFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize, int offset_in_block) { bool read = true; int offset, max_size; @@ -1073,18 +1033,19 @@ String LoadFromFile(SettingsType settingsType, int index, char *fname, byte *mem if ((datasize + offset_in_block) > max_size) { return getSettingsFileDatasizeError(read, settingsType, index, datasize, max_size); } - return LoadFromFile(fname, (offset + offset_in_block), memAddress, datasize); + String fname = SettingsType::getSettingsFileName(settingsType); + return LoadFromFile(fname.c_str(), (offset + offset_in_block), memAddress, datasize); } -String LoadFromFile(SettingsType settingsType, int index, char *fname, byte *memAddress, int datasize) { - return LoadFromFile(settingsType, index, fname, memAddress, datasize, 0); +String LoadFromFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize) { + return LoadFromFile(settingsType, index, memAddress, datasize, 0); } -String SaveToFile(SettingsType settingsType, int index, char *fname, byte *memAddress, int datasize) { - return SaveToFile(settingsType, index, fname, memAddress, datasize, 0); +String SaveToFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize) { + return SaveToFile(settingsType, index, memAddress, datasize, 0); } -String SaveToFile(SettingsType settingsType, int index, char *fname, byte *memAddress, int datasize, int posInBlock) { +String SaveToFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize, int posInBlock) { bool read = false; int offset, max_size; @@ -1095,17 +1056,19 @@ String SaveToFile(SettingsType settingsType, int index, char *fname, byte *memAd if ((datasize > max_size) || ((posInBlock + datasize) > max_size)) { return getSettingsFileDatasizeError(read, settingsType, index, datasize, max_size); } - return SaveToFile(fname, offset + posInBlock, memAddress, datasize); + String fname = SettingsType::getSettingsFileName(settingsType); + return SaveToFile(fname.c_str(), offset + posInBlock, memAddress, datasize); } -String ClearInFile(SettingsType settingsType, int index, char *fname) { +String ClearInFile(SettingsType::Enum settingsType, int index) { bool read = false; int offset, max_size; if (!getAndLogSettingsParameters(read, settingsType, index, offset, max_size)) { return getSettingsFileIndexRangeError(read, settingsType, index); } - return ClearInFile(fname, offset, max_size); + String fname = SettingsType::getSettingsFileName(settingsType); + return ClearInFile(fname.c_str(), offset, max_size); } /********************************************************************************************\ diff --git a/src/ESPEasyWiFiEvent.cpp b/src/ESPEasyWiFiEvent.cpp index 2664913a0..e8ac039e3 100644 --- a/src/ESPEasyWiFiEvent.cpp +++ b/src/ESPEasyWiFiEvent.cpp @@ -29,7 +29,7 @@ void setUseStaticIP(bool enabled) { void markGotIP() { lastGetIPmoment = millis(); - wifiStatus |= ESPEASY_WIFI_GOT_IP; + wifiStatus &= ~ESPEASY_WIFI_GOT_IP; processedGotIP = false; } @@ -59,7 +59,6 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { last_ssid = (const char*) ssid_copy; lastConnectMoment = millis(); processedConnect = false; - wifiStatus |= ESPEASY_WIFI_CONNECTED; break; } case SYSTEM_EVENT_STA_DISCONNECTED: @@ -77,7 +76,6 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { } processedDisconnect = false; lastDisconnectReason = static_cast(info.disconnected.reason); - wifiStatus |= ESPEASY_WIFI_DISCONNECTED; } break; case SYSTEM_EVENT_STA_GOT_IP: @@ -113,7 +111,6 @@ void WiFiEvent(system_event_id_t event, system_event_info_t info) { void onConnected(const WiFiEventStationModeConnected& event) { lastConnectMoment = millis(); processedConnect = false; - wifiStatus |= ESPEASY_WIFI_CONNECTED; channel_changed = RTC.lastWiFiChannel != event.channel; RTC.lastWiFiChannel = event.channel; last_ssid = event.ssid; @@ -137,7 +134,6 @@ void onDisconnect(const WiFiEventStationModeDisconnected& event) { lastConnectedDuration = timeDiff(lastConnectMoment, lastDisconnectMoment); } lastDisconnectReason = event.reason; - wifiStatus = ESPEASY_WIFI_DISCONNECTED; if (WiFi.status() == WL_CONNECTED) { // See https://github.com/esp8266/Arduino/issues/5912 diff --git a/src/ESPEasyWifi_ProcessEvent.ino b/src/ESPEasyWifi_ProcessEvent.ino index 120669308..3f8e563d5 100644 --- a/src/ESPEasyWifi_ProcessEvent.ino +++ b/src/ESPEasyWifi_ProcessEvent.ino @@ -61,9 +61,26 @@ void handle_unprocessedWiFiEvents() // The actual connection has been made, no need to wait for IP to release this semaphore. wifiConnectInProgress = false; } + if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) { + if (WiFi.isConnected()) { + // Apparently we did miss some WiFi events. + if ((wifiStatus & ESPEASY_WIFI_CONNECTED) == 0) { + addLog(LOG_LEVEL_DEBUG, F("WiFi : Force 'WiFi Connected' event")); + processedConnect = false; + } - if ((wifiStatus & ESPEASY_WIFI_GOT_IP) && (wifiStatus & ESPEASY_WIFI_CONNECTED) && WiFi.isConnected()) { - markWiFi_services_initialized(); + if ((wifiStatus & ESPEASY_WIFI_GOT_IP) == 0) { + addLog(LOG_LEVEL_DEBUG, F("WiFi : Force 'WiFi Got IP' event")); + processedGotIP = false; + } + } + } + + + if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) { + if ((wifiStatus & ESPEASY_WIFI_GOT_IP) && (wifiStatus & ESPEASY_WIFI_CONNECTED)) { + markWiFi_services_initialized(); + } } } else if (!WiFiConnected()) { // Somehow the WiFi has entered a limbo state. @@ -202,6 +219,10 @@ void processGotIP() { if (processedGotIP) { return; } + if ((wifiStatus & ESPEASY_WIFI_CONNECTED) == 0) { + // Only process GotIP events if we are connected. + return; + } IPAddress ip = WiFi.localIP(); if (!useStaticIP()) { @@ -416,6 +437,9 @@ void processScanDone() { void markWiFi_services_initialized() { + addLog(LOG_LEVEL_DEBUG, F("WiFi : WiFi services initialized")); wifiStatus = ESPEASY_WIFI_SERVICES_INITIALIZED; wifiConnectInProgress = false; + + processedDHCPTimeout = true; // FIXME TD-er: Is this ever happening? } \ No newline at end of file diff --git a/src/ESPEasy_buildinfo.h b/src/ESPEasy_buildinfo.h index baaeaa71f..d87055c12 100644 --- a/src/ESPEasy_buildinfo.h +++ b/src/ESPEasy_buildinfo.h @@ -20,7 +20,7 @@ #endif // if defined(ESP32) -#define BUILD 20105 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) +#define BUILD 20106 // git version e.g. "20103" can be read as "2.1.03" (stored in int16_t) #if defined(ESP8266) # define BUILD_NOTES " - Mega" #endif // if defined(ESP8266) diff --git a/src/ESPEasy_checks.ino b/src/ESPEasy_checks.ino index ea444e1b8..be00efd91 100644 --- a/src/ESPEasy_checks.ino +++ b/src/ESPEasy_checks.ino @@ -36,7 +36,7 @@ void run_compiletime_checks() { check_size(); const unsigned int SettingsStructSize = (248 + 82 * TASKS_MAX); check_size(); - check_size(); + check_size(); check_size(); check_size(); check_size(); // Is not stored diff --git a/src/ESPEasy_fdwdecl.h b/src/ESPEasy_fdwdecl.h index 3774846f5..611906447 100644 --- a/src/ESPEasy_fdwdecl.h +++ b/src/ESPEasy_fdwdecl.h @@ -2,6 +2,7 @@ #define ESPEASY_FWD_DECL_H #include "ESPEasy_common.h" +#include "src/DataStructs/SettingsType.h" #include "src/DataStructs/ESPEasy_EventStruct.h" #include "src/Globals/CPlugins.h" @@ -156,6 +157,19 @@ void taskClear(taskIndex_t taskIndex, bool save); void SensorSendTask(taskIndex_t TaskIndex); bool remoteConfig(struct EventStruct *event, const String& string); +String getControllerParameterInternalName(protocolIndex_t ProtocolIndex, ControllerSettingsStruct::VarType parameterIdx); +void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettings, controllerIndex_t controllerindex, ControllerSettingsStruct::VarType varType); +void saveControllerParameterForm(ControllerSettingsStruct& ControllerSettings, controllerIndex_t controllerindex, ControllerSettingsStruct::VarType varType); + +String SaveToFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize); +String SaveToFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize, int posInBlock); +String LoadFromFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize, int offset_in_block); +String LoadFromFile(SettingsType::Enum settingsType, int index, byte *memAddress, int datasize); +String ClearInFile(SettingsType::Enum settingsType, int index); +String LoadStringArray(SettingsType::Enum settingsType, int index, String strings[], uint16_t nrStrings, uint16_t maxStringLength); +String SaveStringArray(SettingsType::Enum settingsType, int index, const String strings[], uint16_t nrStrings, uint16_t maxStringLength); + + String parseString(const String& string, byte indexFind); String parseStringKeepCase(const String& string, byte indexFind); String parseStringToEnd(const String& string, byte indexFind); diff --git a/src/Hardware.ino b/src/Hardware.ino index f6e53bc73..e06b9b451 100644 --- a/src/Hardware.ino +++ b/src/Hardware.ino @@ -87,8 +87,7 @@ void initI2C() { // configure hardware pins according to eeprom settings. if (Settings.Pin_i2c_sda != -1) { - String log = F("INIT : I2C"); - addLog(LOG_LEVEL_INFO, log); + addLog(LOG_LEVEL_INFO, F("INIT : I2C")); Wire.setClock(Settings.I2C_clockSpeed); Wire.begin(Settings.Pin_i2c_sda, Settings.Pin_i2c_scl); @@ -120,8 +119,7 @@ void initI2C() { if (status & 0x1) { - String log = F("INIT : Reset by WD!"); - addLog(LOG_LEVEL_ERROR, log); + addLog(LOG_LEVEL_ERROR, F("INIT : Reset by WD!")); lastBootCause = BOOT_CAUSE_EXT_WD; } } diff --git a/src/Misc.ino b/src/Misc.ino index d5ba02ab6..9fd729a27 100644 --- a/src/Misc.ino +++ b/src/Misc.ino @@ -32,19 +32,6 @@ String getNodeTypeDisplayString(byte nodeType) { return ""; } -String getSettingsTypeString(SettingsType settingsType) { - switch (settingsType) { - case BasicSettings_Type: return F("Settings"); - case TaskSettings_Type: return F("TaskSettings"); - case CustomTaskSettings_Type: return F("CustomTaskSettings"); - case ControllerSettings_Type: return F("ControllerSettings"); - case CustomControllerSettings_Type: return F("CustomControllerSettings"); - case NotificationSettings_Type: return F("NotificationSettings"); - default: - break; - } - return ""; -} #ifdef USES_MQTT String getMQTT_state() { @@ -1213,9 +1200,9 @@ void ResetFactory() // advanced Settings Settings.UseRules = DEFAULT_USE_RULES; Settings.ControllerEnabled[0] = DEFAULT_CONTROLLER_ENABLED; - Settings.MQTTRetainFlag = DEFAULT_MQTT_RETAIN; - Settings.MessageDelay = DEFAULT_MQTT_DELAY; - Settings.MQTTUseUnitNameAsClientId = DEFAULT_MQTT_USE_UNITNAME_AS_CLIENTID; + Settings.MQTTRetainFlag_unused = DEFAULT_MQTT_RETAIN; + Settings.MessageDelay_unused = DEFAULT_MQTT_DELAY; + Settings.MQTTUseUnitNameAsClientId_unused = DEFAULT_MQTT_USE_UNITNAME_AS_CLIENTID; Settings.UseSerial = DEFAULT_USE_SERIAL; @@ -1249,10 +1236,11 @@ void ResetFactory() str2ip((char*)DEFAULT_SERVER, ControllerSettings.IP); ControllerSettings.setHostname(F(DEFAULT_SERVER_HOST)); ControllerSettings.UseDNS = DEFAULT_SERVER_USEDNS; + ControllerSettings.useExtendedCredentials(DEFAULT_USE_EXTD_CONTROLLER_CREDENTIALS); ControllerSettings.Port = DEFAULT_PORT; + setControllerUser(0, ControllerSettings, F(DEFAULT_CONTROLLER_USER)); + setControllerPass(0, ControllerSettings, F(DEFAULT_CONTROLLER_PASS)); SaveControllerSettings(0, ControllerSettings); - strcpy_P(SecuritySettings.ControllerUser[0], PSTR(DEFAULT_CONTROLLER_USER)); - strcpy_P(SecuritySettings.ControllerPassword[0], PSTR(DEFAULT_CONTROLLER_PASS)); #endif SaveSettings(); diff --git a/src/Scheduler.ino b/src/Scheduler.ino index e474398cd..3950e4253 100644 --- a/src/Scheduler.ino +++ b/src/Scheduler.ino @@ -562,7 +562,7 @@ void schedule_task_device_timer_at_init(unsigned long task_index) { // Deepsleep is not enabled, add some offset based on the task index // to make sure not all are run at the same time. // This scheduled time may be overriden by the plugin's own init. - runAt += (task_index * 37) + Settings.MessageDelay; + runAt += (task_index * 37) + 100; } else { runAt += (task_index * 11) + 10; } diff --git a/src/StringProvider.ino b/src/StringProvider.ino index b4fcfba00..c5f541c8d 100644 --- a/src/StringProvider.ino +++ b/src/StringProvider.ino @@ -174,8 +174,8 @@ String getValue(LabelType::Enum label) { case LabelType::SYSTEM_LIBRARIES: return getSystemLibraryString(); case LabelType::PLUGIN_COUNT: return String(deviceCount + 1); case LabelType::PLUGIN_DESCRIPTION: return getPluginDescriptionString(); - case LabelType::BUILD_TIME: break; - case LabelType::BINARY_FILENAME: break; + case LabelType::BUILD_TIME: return String(CRCValues.compileDate) + " " + String(CRCValues.compileTime); + case LabelType::BINARY_FILENAME: return String(CRCValues.binaryFilename); case LabelType::SYSLOG_LOG_LEVEL: return getLogLevelDisplayString(Settings.SyslogLevel); case LabelType::SERIAL_LOG_LEVEL: return getLogLevelDisplayString(getSerialLogLevel()); diff --git a/src/WebServer.ino b/src/WebServer.ino index d5e8f92c8..b892473a6 100644 --- a/src/WebServer.ino +++ b/src/WebServer.ino @@ -8,6 +8,7 @@ #include "src/Globals/Device.h" #include "src/Globals/TXBuffer.h" #include "src/Static/WebStaticData.h" +#include "src/DataStructs/SettingsType.h" @@ -958,26 +959,6 @@ void createSvgTextElement(const String& text, float textXoffset, float textYoffs addHtml(F("\n")); } -unsigned int getSettingsTypeColor(SettingsType settingsType) { - switch (settingsType) { - case BasicSettings_Type: - return 0x5F0A87; - case TaskSettings_Type: - return 0xEE6352; - case CustomTaskSettings_Type: - return 0x59CD90; - case ControllerSettings_Type: - return 0x3FA7D6; - case CustomControllerSettings_Type: - return 0xFAC05E; - case NotificationSettings_Type: - return 0xF79D84; - default: - break; - } - return 0; -} - #define SVG_BAR_HEIGHT 16 #define SVG_BAR_WIDTH 400 @@ -1045,18 +1026,17 @@ void getConfig_dat_file_layout() { int struct_size = 0; // background - const uint32_t realSize = getFileSize(TaskSettings_Type); + const uint32_t realSize = SettingsType::getFileSize(SettingsType::TaskSettings_Type); createSvgHorRectPath(0xcdcdcd, 0, yOffset, realSize, SVG_BAR_HEIGHT - 2, realSize, SVG_BAR_WIDTH); - for (int st = 0; st < SettingsType_MAX; ++st) { - SettingsType settingsType = static_cast(st); - - if (settingsType != NotificationSettings_Type) { - unsigned int color = getSettingsTypeColor(settingsType); - getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); + for (int st = 0; st < SettingsType::SettingsType_MAX; ++st) { + SettingsType::Enum settingsType = static_cast(st); + if (SettingsType::getSettingsFile(settingsType) == SettingsType::FILE_CONFIG_type) { + unsigned int color = SettingsType::getSVGcolor(settingsType); + SettingsType::getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); for (int i = 0; i < max_index; ++i) { - getSettingsParameters(settingsType, i, offset, max_size); + SettingsType::getSettingsParameters(settingsType, i, offset, max_size); // Struct position createSvgHorRectPath(color, offset, yOffset, max_size, SVG_BAR_HEIGHT - 2, realSize, SVG_BAR_WIDTH); @@ -1067,19 +1047,19 @@ void getConfig_dat_file_layout() { // Text labels float textXoffset = SVG_BAR_WIDTH + 2; float textYoffset = yOffset + 0.9 * SVG_BAR_HEIGHT; - createSvgTextElement(F("Config.dat"), textXoffset, textYoffset); + createSvgTextElement(SettingsType::getSettingsFileName(SettingsType::TaskSettings_Type), textXoffset, textYoffset); addHtml(F("\n")); } -void getStorageTableSVG(SettingsType settingsType) { - uint32_t realSize = getFileSize(settingsType); - unsigned int color = getSettingsTypeColor(settingsType); +void getStorageTableSVG(SettingsType::Enum settingsType) { + uint32_t realSize = SettingsType::getFileSize(settingsType); + unsigned int color = SettingsType::getSVGcolor(settingsType); const int shiftY = 2; int max_index, offset, max_size; int struct_size = 0; - getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); + SettingsType::getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); if (max_index == 0) { return; } @@ -1088,7 +1068,7 @@ void getStorageTableSVG(SettingsType settingsType) { float yOffset = shiftY; for (int i = 0; i < max_index; ++i) { - getSettingsParameters(settingsType, i, offset, max_size); + SettingsType::getSettingsParameters(settingsType, i, offset, max_size); // background createSvgHorRectPath(0xcdcdcd, 0, yOffset, realSize, SVG_BAR_HEIGHT - 2, realSize, SVG_BAR_WIDTH); diff --git a/src/WebServer_AdvancedConfigPage.ino b/src/WebServer_AdvancedConfigPage.ino index 8cc88b6b3..1ceaafeed 100644 --- a/src/WebServer_AdvancedConfigPage.ino +++ b/src/WebServer_AdvancedConfigPage.ino @@ -27,7 +27,7 @@ void handle_advanced() { if (edit.length() != 0) { - Settings.MessageDelay = getFormItemInt(F("messagedelay")); +// 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; @@ -59,11 +59,13 @@ void handle_advanced() { Settings.WireClockStretchLimit = getFormItemInt(F("wireclockstretchlimit")); Settings.UseRules = isFormItemChecked(F("userules")); Settings.ConnectionFailuresThreshold = getFormItemInt(F("cft")); - Settings.MQTTRetainFlag = isFormItemChecked(F("mqttretainflag")); Settings.ArduinoOTAEnable = isFormItemChecked(F("arduinootaenable")); Settings.UseRTOSMultitasking = isFormItemChecked(F("usertosmultitasking")); - Settings.MQTTUseUnitNameAsClientId = isFormItemChecked(F("mqttuseunitnameasclientid")); - Settings.uniqueMQTTclientIdReconnect(isFormItemChecked(F("uniquemqttclientidreconnect"))); + + // MQTT settings now moved to the controller settings. +// Settings.MQTTRetainFlag_unused = isFormItemChecked(F("mqttretainflag")); +// Settings.MQTTUseUnitNameAsClientId = isFormItemChecked(F("mqttuseunitnameasclientid")); +// Settings.uniqueMQTTclientIdReconnect(isFormItemChecked(F("uniquemqttclientidreconnect"))); Settings.Latitude = getFormItemFloat(F("latitude")); Settings.Longitude = getFormItemFloat(F("longitude")); Settings.OldRulesEngine(isFormItemChecked(F("oldrulesengine"))); @@ -97,13 +99,17 @@ void handle_advanced() { addFormNote(F("Perform less strict parsing on last argument of some commands (e.g. publish and sendToHttp)")); addFormCheckBox(F("SendToHTTP wait for ack"), F("sendtohttp_ack"), Settings.SendToHttp_ack()); + /* + // MQTT settings now moved to the controller settings. addFormSubHeader(F("Controller Settings")); - addFormCheckBox(F("MQTT Retain Msg"), F("mqttretainflag"), Settings.MQTTRetainFlag); - addFormNumericBox(F("Message Interval"), F("messagedelay"), Settings.MessageDelay, 0, INT_MAX); + addFormNumericBox(F("Message Interval"), F("messagedelay"), Settings.MessageDelay_unused, 0, INT_MAX); addUnit(F("ms")); + + addFormCheckBox(F("MQTT Retain Msg"), F("mqttretainflag"), Settings.MQTTRetainFlag_unused); addFormCheckBox(F("MQTT use unit name as ClientId"), F("mqttuseunitnameasclientid"), Settings.MQTTUseUnitNameAsClientId); - addFormCheckBox(F("MQTT change ClientId at reconnect"), F("uniquemqttclientidreconnect"), Settings.uniqueMQTTclientIdReconnect()); + addFormCheckBox(F("MQTT change ClientId at reconnect"), F("uniquemqttclientidreconnect"), Settings.uniqueMQTTclientIdReconnect_unused()); +*/ addFormSubHeader(F("NTP Settings")); diff --git a/src/WebServer_ControllerPage.ino b/src/WebServer_ControllerPage.ino index eaed516bb..3faadaeb6 100644 --- a/src/WebServer_ControllerPage.ino +++ b/src/WebServer_ControllerPage.ino @@ -126,8 +126,9 @@ void handle_controllers_clearLoadDefaults(byte controllerindex, ControllerSettin void handle_controllers_CopySubmittedSettings(byte controllerindex, ControllerSettingsStruct& ControllerSettings) { // copy all settings to controller settings struct - for (int parameterIdx = 1; parameterIdx <= CONTROLLER_ENABLED; ++parameterIdx) { - saveControllerParameterForm(ControllerSettings, controllerindex, parameterIdx); + for (int parameterIdx = 0; parameterIdx <= ControllerSettingsStruct::CONTROLLER_ENABLED; ++parameterIdx) { + ControllerSettingsStruct::VarType varType = static_cast(parameterIdx); + saveControllerParameterForm(ControllerSettings, controllerindex, varType); } protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(controllerindex); @@ -259,72 +260,83 @@ void handle_controllers_ControllerSettingsPage(controllerIndex_t controllerindex if (!Protocol[ProtocolIndex].Custom) { if (Protocol[ProtocolIndex].usesHost) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_USE_DNS); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_USE_DNS); if (ControllerSettings.UseDNS) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_HOSTNAME); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_HOSTNAME); } else { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_IP); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_IP); } } - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_PORT); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_PORT); if (Protocol[ProtocolIndex].usesQueue) { addTableSeparator(F("Controller Queue"), 2, 3); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_MIN_SEND_INTERVAL); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_MAX_QUEUE_DEPTH); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_MAX_RETRIES); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_FULL_QUEUE_ACTION); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_MIN_SEND_INTERVAL); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_MAX_QUEUE_DEPTH); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_MAX_RETRIES); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION); } if (Protocol[ProtocolIndex].usesCheckReply) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_CHECK_REPLY); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_CHECK_REPLY); } if (Protocol[ProtocolIndex].usesTimeout) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_TIMEOUT); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_TIMEOUT); } if (Protocol[ProtocolIndex].usesSampleSets) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_SAMPLE_SET_INITIATOR); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_SAMPLE_SET_INITIATOR); } if (Protocol[ProtocolIndex].usesAccount || Protocol[ProtocolIndex].usesPassword) { addTableSeparator(F("Credentials"), 2, 3); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_USE_EXTENDED_CREDENTIALS); } if (Protocol[ProtocolIndex].usesAccount) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_USER); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_USER); } if (Protocol[ProtocolIndex].usesPassword) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_PASS); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_PASS); } - + #ifdef USES_MQTT if (Protocol[ProtocolIndex].usesMQTT) { addTableSeparator(F("MQTT"), 2, 3); + + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_CLIENT_ID); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_UNIQUE_CLIENT_ID_RECONNECT); + addRowLabel(F("Current Client ID")); + addHtml(getMQTTclientID(ControllerSettings)); + addFormNote(F("Updated on load of this page")); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_RETAINFLAG); } + #endif // USES_MQTT + if (Protocol[ProtocolIndex].usesTemplate || Protocol[ProtocolIndex].usesMQTT) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_SUBSCRIBE); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_PUBLISH); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_SUBSCRIBE); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_PUBLISH); } - + #ifdef USES_MQTT if (Protocol[ProtocolIndex].usesMQTT) { - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_LWT_TOPIC); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_LWT_CONNECT_MESSAGE); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_LWT_DISCONNECT_MESSAGE); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_SEND_LWT); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_WILL_RETAIN); - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_CLEAN_SESSION); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_LWT_TOPIC); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_LWT_CONNECT_MESSAGE); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_LWT_DISCONNECT_MESSAGE); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_SEND_LWT); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_WILL_RETAIN); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_CLEAN_SESSION); } + #endif // USES_MQTT } { // Load controller specific settings @@ -338,7 +350,7 @@ void handle_controllers_ControllerSettingsPage(controllerIndex_t controllerindex addHtmlError(F("Bug in CPlugin::Function::CPLUGIN_WEBFORM_LOAD, should not append to string, use addHtml() instead")); } } - addControllerParameterForm(ControllerSettings, controllerindex, CONTROLLER_ENABLED); + addControllerParameterForm(ControllerSettings, controllerindex, ControllerSettingsStruct::CONTROLLER_ENABLED); } addFormSeparator(2); diff --git a/src/WebServer_Markup_Buttons.ino b/src/WebServer_Markup_Buttons.ino index 2b2f05cb4..00b15c8d3 100644 --- a/src/WebServer_Markup_Buttons.ino +++ b/src/WebServer_Markup_Buttons.ino @@ -35,7 +35,7 @@ void addButtonWithSvg(const String& url, const String& label, const String& svgP altText.reserve(7 + label.length()); altText = F("' alt='"); altText += label; - addHtml(label); + addHtml(altText); } #endif diff --git a/src/WebServer_SysInfoPage.ino b/src/WebServer_SysInfoPage.ino index 73add7c82..f06bde8f4 100644 --- a/src/WebServer_SysInfoPage.ino +++ b/src/WebServer_SysInfoPage.ino @@ -434,10 +434,7 @@ void handle_sysinfo_Firmware() { addHtml(F("passed.")); } } - addRowLabel_copy(getLabel(LabelType::BUILD_TIME)); - addHtml(String(CRCValues.compileDate)); - addHtml(" "); - addHtml(String(CRCValues.compileTime)); + addRowLabelValue_copy(LabelType::BUILD_TIME); addRowLabel_copy(getLabel(LabelType::BINARY_FILENAME)); @@ -665,10 +662,12 @@ void handle_sysinfo_Storage() { html_TD(); addHtml(F("(offset / size per item / index)")); - for (int st = 0; st < SettingsType_MAX; ++st) { - SettingsType settingsType = static_cast(st); + for (int st = 0; st < SettingsType::SettingsType_MAX; ++st) { + SettingsType::Enum settingsType = static_cast(st); html_TR_TD(); - addHtml(getSettingsTypeString(settingsType)); + addHtml(SettingsType::getSettingsTypeString(settingsType)); + html_BR(); + addHtml(SettingsType::getSettingsFileName(settingsType)); html_TD(); getStorageTableSVG(settingsType); } diff --git a/src/_C002.ino b/src/_C002.ino index 7e7a38d67..6a3626d1c 100644 --- a/src/_C002.ino +++ b/src/_C002.ino @@ -238,7 +238,7 @@ bool CPlugin_002(CPlugin::Function function, struct EventStruct *event, String& String pubname = ControllerSettings.Publish; parseControllerVariables(pubname, event, false); - success = MQTTpublish(event->ControllerIndex, pubname.c_str(), json.c_str(), Settings.MQTTRetainFlag); + success = MQTTpublish(event->ControllerIndex, pubname.c_str(), json.c_str(), ControllerSettings.mqtt_retainFlag()); } // if ixd !=0 else { diff --git a/src/_C003.ino b/src/_C003.ino index 90f53aa91..3582ef135 100644 --- a/src/_C003.ino +++ b/src/_C003.ino @@ -105,7 +105,7 @@ bool do_process_c003_delay_queue(int controller_number, const C003_queue_element } addLog(LOG_LEVEL_DEBUG, F("TELNT: Sending pw")); - client.println(SecuritySettings.ControllerPassword[element.controller_idx]); + client.println(getControllerPass(element.controller_idx, ControllerSettings)); delay(100); while (client_available(client)) client.read(); diff --git a/src/_C004.ino b/src/_C004.ino index e41fc656c..b9eb3886b 100644 --- a/src/_C004.ino +++ b/src/_C004.ino @@ -42,10 +42,10 @@ bool CPlugin_004(CPlugin::Function function, struct EventStruct *event, String& { success = true; switch (event->idx) { - case CONTROLLER_USER: + case ControllerSettingsStruct::CONTROLLER_USER: string = F("ThingHTTP Name"); break; - case CONTROLLER_PASS: + case ControllerSettingsStruct::CONTROLLER_PASS: string = F("API Key"); break; default: @@ -88,7 +88,7 @@ bool do_process_c004_delay_queue(int controller_number, const C004_queue_element return false; String postDataStr = F("api_key="); - postDataStr += SecuritySettings.ControllerPassword[element.controller_idx]; // used for API key + postDataStr += getControllerPass(element.controller_idx, ControllerSettings); // used for API key if (element.sensorType == SENSOR_TYPE_STRING) { postDataStr += F("&status="); diff --git a/src/_C005.ino b/src/_C005.ino index 1d0b49ce2..896301013 100644 --- a/src/_C005.ino +++ b/src/_C005.ino @@ -121,7 +121,7 @@ bool CPlugin_005(CPlugin::Function function, struct EventStruct *event, String& tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), Settings.MQTTRetainFlag); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); #ifndef BUILD_NO_DEBUG String log = F("MQTT : "); log += tmppubname; diff --git a/src/_C006.ino b/src/_C006.ino index 4efae32be..f7eb9d155 100644 --- a/src/_C006.ino +++ b/src/_C006.ino @@ -110,7 +110,7 @@ bool CPlugin_006(CPlugin::Function function, struct EventStruct *event, String& String tmppubname = pubname; tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), Settings.MQTTRetainFlag); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); } break; } diff --git a/src/_C007.ino b/src/_C007.ino index fe54a81fd..a4fcd916b 100644 --- a/src/_C007.ino +++ b/src/_C007.ino @@ -92,7 +92,7 @@ bool do_process_c007_delay_queue(int controller_number, const C007_queue_element } url += "}"; url += F("&apikey="); - url += SecuritySettings.ControllerPassword[element.controller_idx]; // "0UDNN17RW6XAS2E5" // api key + url += getControllerPass(element.controller_idx, ControllerSettings); // "0UDNN17RW6XAS2E5" // api key if (Settings.SerialLogLevel >= LOG_LEVEL_DEBUG_MORE) serialPrintln(url); diff --git a/src/_C012.ino b/src/_C012.ino index 46cfcd02b..7ed427b5d 100644 --- a/src/_C012.ino +++ b/src/_C012.ino @@ -103,7 +103,7 @@ boolean Blynk_get(const String& command, controllerIndex_t controllerIndex, floa MakeControllerSettings(ControllerSettings); LoadControllerSettings(controllerIndex, ControllerSettings); - if ((SecuritySettings.ControllerPassword[controllerIndex][0] == 0)) { + if ((getControllerPass(controllerIndex, ControllerSettings).length() == 0)) { addLog(LOG_LEVEL_ERROR, F("Blynk : No password set")); return false; } @@ -117,7 +117,7 @@ boolean Blynk_get(const String& command, controllerIndex_t controllerIndex, floa char request[300] = {0}; sprintf_P(request, PSTR("GET /%s/%s HTTP/1.1\r\n Host: %s \r\n Connection: close\r\n\r\n"), - SecuritySettings.ControllerPassword[controllerIndex], + getControllerPass(controllerIndex, ControllerSettings).c_str(), command.c_str(), ControllerSettings.getHost().c_str()); addLog(LOG_LEVEL_DEBUG, request); @@ -173,7 +173,7 @@ boolean Blynk_get(const String& command, controllerIndex_t controllerIndex, floa client.stop(); // important - backgroundtasks - free mem - unsigned long timer = millis() + Settings.MessageDelay; + unsigned long timer = millis() + ControllerSettings.ClientTimeout; while (!timeOutReached(timer)) backgroundtasks(); diff --git a/src/_C014.ino b/src/_C014.ino index 48c83103e..114ffada4 100644 --- a/src/_C014.ino +++ b/src/_C014.ino @@ -709,7 +709,7 @@ bool CPlugin_014(CPlugin::Function function, struct EventStruct *event, String& tmppubname.replace(F("%valname%"), ExtraTaskSettings.TaskDeviceValueNames[x]); value = formatUserVarNoCheck(event, x); - MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), Settings.MQTTRetainFlag); + MQTTpublish(event->ControllerIndex, tmppubname.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); if (loglevelActiveFor(LOG_LEVEL_DEBUG)) { String log = F("C014 : Sent to "); log += tmppubname; diff --git a/src/_C015.ino b/src/_C015.ino index b0d4a390b..675b9a82a 100644 --- a/src/_C015.ino +++ b/src/_C015.ino @@ -234,7 +234,7 @@ boolean Blynk_keep_connection_c015(int controllerIndex, ControllerSettingsStruct return false; if (!Blynk.connected()){ - String auth = SecuritySettings.ControllerPassword[controllerIndex]; + String auth = getControllerPass(controllerIndex, ControllerSettings); boolean connectDefault = false; if (timePassedSince(_C015_LastConnectAttempt[controllerIndex]) < CPLUGIN_015_RECONNECT_INTERVAL){ @@ -363,7 +363,7 @@ String Command_Blynk_Set_c015(struct EventStruct *event, const char* Line){ boolean Blynk_send_c015(const String& value, int vPin ) { Blynk.virtualWrite(vPin, value); - unsigned long timer = millis() + Settings.MessageDelay; + unsigned long timer = millis() + ControllerSettings.ClientTimeout; while (!timeOutReached(timer)) backgroundtasks(); return true; diff --git a/src/_C018.ino b/src/_C018.ino index c3fb53351..463492f16 100644 --- a/src/_C018.ino +++ b/src/_C018.ino @@ -447,8 +447,8 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& C018_data.setFrequencyPlan(static_cast(customConfig.frequencyplan)); if (customConfig.joinmethod == C018_USE_OTAA) { - String AppEUI = SecuritySettings.ControllerUser[event->ControllerIndex]; - String AppKey = SecuritySettings.ControllerPassword[event->ControllerIndex]; + String AppEUI = getControllerUser(event->ControllerIndex, ControllerSettings); + String AppKey = getControllerPass(event->ControllerIndex, ControllerSettings); C018_data.initOTAA(AppEUI, AppKey, customConfig.DeviceEUI); } else { @@ -472,8 +472,8 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(event->ControllerIndex); html_add_script(false); addHtml(F("function joinChanged(elem){ var styleOTAA = elem.value == 0 ? '' : 'none'; var styleABP = elem.value == 1 ? '' : 'none';")); - addHtml(c018_add_joinChanged_script_element_line(getControllerParameterInternalName(ProtocolIndex, CONTROLLER_USER), true)); - addHtml(c018_add_joinChanged_script_element_line(getControllerParameterInternalName(ProtocolIndex, CONTROLLER_PASS), true)); + addHtml(c018_add_joinChanged_script_element_line(getControllerParameterInternalName(ProtocolIndex, ControllerSettingsStruct::CONTROLLER_USER), true)); + addHtml(c018_add_joinChanged_script_element_line(getControllerParameterInternalName(ProtocolIndex, ControllerSettingsStruct::CONTROLLER_PASS), true)); addHtml(c018_add_joinChanged_script_element_line(F("deveui"), true)); addHtml(c018_add_joinChanged_script_element_line(F("deveui_note"), true)); @@ -607,16 +607,16 @@ bool CPlugin_018(CPlugin::Function function, struct EventStruct *event, String& success = true; switch (event->idx) { - case CONTROLLER_USER: + case ControllerSettingsStruct::CONTROLLER_USER: string = F("AppEUI"); break; - case CONTROLLER_PASS: + case ControllerSettingsStruct::CONTROLLER_PASS: string = F("AppKey"); break; - case CONTROLLER_TIMEOUT: + case ControllerSettingsStruct::CONTROLLER_TIMEOUT: string = F("Module Timeout"); break; - case CONTROLLER_PORT: + case ControllerSettingsStruct::CONTROLLER_PORT: string = F("Port"); default: success = false; diff --git a/src/_CPlugin_Helper.cpp b/src/_CPlugin_Helper.cpp index 606a3d04f..0428d449d 100644 --- a/src/_CPlugin_Helper.cpp +++ b/src/_CPlugin_Helper.cpp @@ -100,16 +100,15 @@ String get_auth_header(const String& user, const String& pass) { return authHeader; } -String get_auth_header(int controller_index) { +String get_auth_header(int controller_index, const ControllerSettingsStruct& ControllerSettings) { String authHeader = ""; if (validControllerIndex(controller_index)) { - if ((SecuritySettings.ControllerUser[controller_index][0] != 0) && - (SecuritySettings.ControllerPassword[controller_index][0] != 0)) + if (hasControllerCredentialsSet(controller_index, ControllerSettings)) { authHeader = get_auth_header( - String(SecuritySettings.ControllerUser[controller_index]), - String(SecuritySettings.ControllerPassword[controller_index])); + getControllerUser(controller_index, ControllerSettings), + getControllerPass(controller_index, ControllerSettings)); } } else { addLog(LOG_LEVEL_ERROR, F("Invalid controller index")); @@ -215,7 +214,7 @@ String create_http_request_auth( defaultport ? ControllerSettings.getHost() : ControllerSettings.getHostPortString(), method, uri, - get_auth_header(controller_index), + get_auth_header(controller_index, ControllerSettings), "", // additional_options content_length); } @@ -428,3 +427,48 @@ bool send_via_http(const String& logIdentifier, WiFiClient& client, const String bool send_via_http(int controller_number, WiFiClient& client, const String& postStr, bool must_check_reply) { return send_via_http(get_formatted_Controller_number(controller_number), client, postStr, must_check_reply); } + + +String getControllerUser(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings) +{ + if (!validControllerIndex(controller_idx)) return ""; + if (ControllerSettings.useExtendedCredentials()) { + return ExtendedControllerCredentials.getControllerUser(controller_idx); + } + return SecuritySettings.ControllerUser[controller_idx]; +} + +String getControllerPass(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings) +{ + if (!validControllerIndex(controller_idx)) return ""; + if (ControllerSettings.useExtendedCredentials()) { + return ExtendedControllerCredentials.getControllerPass(controller_idx); + } + return SecuritySettings.ControllerPassword[controller_idx]; +} + +void setControllerUser(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings, const String& value) +{ + if (!validControllerIndex(controller_idx)) return; + if (ControllerSettings.useExtendedCredentials()) { + ExtendedControllerCredentials.setControllerUser(controller_idx, value); + } else { + safe_strncpy(SecuritySettings.ControllerUser[controller_idx], value, sizeof(SecuritySettings.ControllerUser[0])); + } +} + +void setControllerPass(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings, const String& value) +{ + if (!validControllerIndex(controller_idx)) return; + if (ControllerSettings.useExtendedCredentials()) { + ExtendedControllerCredentials.setControllerPass(controller_idx, value); + } else { + safe_strncpy(SecuritySettings.ControllerPassword[controller_idx], value, sizeof(SecuritySettings.ControllerPassword[0])); + } +} + +bool hasControllerCredentialsSet(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings) +{ + return getControllerUser(controller_idx, ControllerSettings).length() != 0 && + getControllerPass(controller_idx, ControllerSettings).length() != 0; +} \ No newline at end of file diff --git a/src/_CPlugin_Helper.h b/src/_CPlugin_Helper.h index 18cb681bf..8bddf7a48 100644 --- a/src/_CPlugin_Helper.h +++ b/src/_CPlugin_Helper.h @@ -21,7 +21,7 @@ String get_formatted_Controller_number(cpluginID_t cpluginID); String get_auth_header(const String& user, const String& pass); -String get_auth_header(int controller_index); +String get_auth_header(int controller_index, const ControllerSettingsStruct& ControllerSettings); String get_user_agent_request_header_field(); @@ -74,5 +74,12 @@ bool send_via_http(const String& logIdentifier, WiFiClient& client, const String bool send_via_http(int controller_number, WiFiClient& client, const String& postStr, bool must_check_reply); +String getControllerUser(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings); +String getControllerPass(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings); +void setControllerUser(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings, const String& value); +void setControllerPass(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings, const String& value); + +bool hasControllerCredentialsSet(controllerIndex_t controller_idx, const ControllerSettingsStruct& ControllerSettings); + #endif // CPLUGIN_HELPER_H diff --git a/src/_CPlugin_Helper_webform.ino b/src/_CPlugin_Helper_webform.ino index fc15504fc..b3c753b2b 100644 --- a/src/_CPlugin_Helper_webform.ino +++ b/src/_CPlugin_Helper_webform.ino @@ -1,11 +1,13 @@ -#include "src/Globals/CPlugins.h" #include "ESPEasy_plugindefs.h" +#include "src/Globals/CPlugins.h" +#include "src/Globals/SecuritySettings.h" +#include "src/DataStructs/ESPEasy_EventStruct.h" /*********************************************************************************************\ * Functions to load and store controller settings on the web page. \*********************************************************************************************/ -String getControllerParameterName(protocolIndex_t ProtocolIndex, byte parameterIdx, bool displayName, bool& isAlternative) { +String getControllerParameterName(protocolIndex_t ProtocolIndex, ControllerSettingsStruct::VarType parameterIdx, bool displayName, bool& isAlternative) { String name; if (displayName) { @@ -21,31 +23,35 @@ String getControllerParameterName(protocolIndex_t ProtocolIndex, byte parameterI isAlternative = false; switch (parameterIdx) { - case CONTROLLER_USE_DNS: name = F("Locate Controller"); break; - case CONTROLLER_HOSTNAME: name = F("Controller Hostname"); break; - case CONTROLLER_IP: name = F("Controller IP"); break; - case CONTROLLER_PORT: name = F("Controller Port"); break; - case CONTROLLER_USER: name = F("Controller User"); break; - case CONTROLLER_PASS: name = F("Controller Password"); break; + case ControllerSettingsStruct::CONTROLLER_USE_DNS: name = F("Locate Controller"); break; + case ControllerSettingsStruct::CONTROLLER_HOSTNAME: name = F("Controller Hostname"); break; + case ControllerSettingsStruct::CONTROLLER_IP: name = F("Controller IP"); break; + case ControllerSettingsStruct::CONTROLLER_PORT: name = F("Controller Port"); break; + case ControllerSettingsStruct::CONTROLLER_USER: name = F("Controller User"); break; + case ControllerSettingsStruct::CONTROLLER_PASS: name = F("Controller Password"); break; - case CONTROLLER_MIN_SEND_INTERVAL: name = F("Minimum Send Interval"); break; - case CONTROLLER_MAX_QUEUE_DEPTH: name = F("Max Queue Depth"); break; - case CONTROLLER_MAX_RETRIES: name = F("Max Retries"); break; - case CONTROLLER_FULL_QUEUE_ACTION: name = F("Full Queue Action"); break; - case CONTROLLER_CHECK_REPLY: name = F("Check Reply"); break; + case ControllerSettingsStruct::CONTROLLER_MIN_SEND_INTERVAL: name = F("Minimum Send Interval"); break; + case ControllerSettingsStruct::CONTROLLER_MAX_QUEUE_DEPTH: name = F("Max Queue Depth"); break; + case ControllerSettingsStruct::CONTROLLER_MAX_RETRIES: name = F("Max Retries"); break; + case ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION: name = F("Full Queue Action"); break; + case ControllerSettingsStruct::CONTROLLER_CHECK_REPLY: name = F("Check Reply"); break; - case CONTROLLER_SUBSCRIBE: name = F("Controller Subscribe"); break; - case CONTROLLER_PUBLISH: name = F("Controller Publish"); break; - case CONTROLLER_LWT_TOPIC: name = F("Controller LWT Topic"); break; - case CONTROLLER_LWT_CONNECT_MESSAGE: name = F("LWT Connect Message"); break; - case CONTROLLER_LWT_DISCONNECT_MESSAGE: name = F("LWT Disconnect Message"); break; - case CONTROLLER_SEND_LWT: name = F("Send LWT to broker"); break; - case CONTROLLER_WILL_RETAIN: name = F("Will Retain"); break; - case CONTROLLER_CLEAN_SESSION: name = F("Clean Session"); break; - case CONTROLLER_TIMEOUT: name = F("Client Timeout"); break; - case CONTROLLER_SAMPLE_SET_INITIATOR: name = F("Sample Set Initiator"); break; + case ControllerSettingsStruct::CONTROLLER_CLIENT_ID: name = F("Controller Client ID"); break; + case ControllerSettingsStruct::CONTROLLER_UNIQUE_CLIENT_ID_RECONNECT: name = F("Unique Client ID on Reconnect"); break; + case ControllerSettingsStruct::CONTROLLER_RETAINFLAG: name = F("Publish Retain Flag"); break; + case ControllerSettingsStruct::CONTROLLER_SUBSCRIBE: name = F("Controller Subscribe"); break; + case ControllerSettingsStruct::CONTROLLER_PUBLISH: name = F("Controller Publish"); break; + case ControllerSettingsStruct::CONTROLLER_LWT_TOPIC: name = F("Controller LWT Topic"); break; + case ControllerSettingsStruct::CONTROLLER_LWT_CONNECT_MESSAGE: name = F("LWT Connect Message"); break; + case ControllerSettingsStruct::CONTROLLER_LWT_DISCONNECT_MESSAGE: name = F("LWT Disconnect Message"); break; + case ControllerSettingsStruct::CONTROLLER_SEND_LWT: name = F("Send LWT to broker"); break; + case ControllerSettingsStruct::CONTROLLER_WILL_RETAIN: name = F("Will Retain"); break; + case ControllerSettingsStruct::CONTROLLER_CLEAN_SESSION: name = F("Clean Session"); break; + case ControllerSettingsStruct::CONTROLLER_USE_EXTENDED_CREDENTIALS: name = F("Use Extended Credentials"); break; + case ControllerSettingsStruct::CONTROLLER_TIMEOUT: name = F("Client Timeout"); break; + case ControllerSettingsStruct::CONTROLLER_SAMPLE_SET_INITIATOR: name = F("Sample Set Initiator"); break; - case CONTROLLER_ENABLED: + case ControllerSettingsStruct::CONTROLLER_ENABLED: if (displayName) { name = F("Enabled"); } else { name = F("controllerenabled"); } @@ -63,31 +69,31 @@ String getControllerParameterName(protocolIndex_t ProtocolIndex, byte parameterI return name; } -String getControllerParameterInternalName(protocolIndex_t ProtocolIndex, byte parameterIdx) { +String getControllerParameterInternalName(protocolIndex_t ProtocolIndex, ControllerSettingsStruct::VarType parameterIdx) { bool isAlternative; // Dummy, not needed for internal name bool displayName = false; return getControllerParameterName(ProtocolIndex, parameterIdx, displayName, isAlternative); } -String getControllerParameterDisplayName(protocolIndex_t ProtocolIndex, byte parameterIdx, bool& isAlternative) { +String getControllerParameterDisplayName(protocolIndex_t ProtocolIndex, ControllerSettingsStruct::VarType parameterIdx, bool& isAlternative) { bool displayName = true; return getControllerParameterName(ProtocolIndex, parameterIdx, displayName, isAlternative); } -void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettings, controllerIndex_t controllerindex, byte parameterIdx) { +void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettings, controllerIndex_t controllerindex, ControllerSettingsStruct::VarType varType) { protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(controllerindex); if (!validProtocolIndex(ProtocolIndex)) { return; } bool isAlternativeDisplayName = false; - String displayName = getControllerParameterDisplayName(ProtocolIndex, parameterIdx, isAlternativeDisplayName); - String internalName = getControllerParameterInternalName(ProtocolIndex, parameterIdx); + String displayName = getControllerParameterDisplayName(ProtocolIndex, varType, isAlternativeDisplayName); + String internalName = getControllerParameterInternalName(ProtocolIndex, varType); - switch (parameterIdx) { - case CONTROLLER_USE_DNS: + switch (varType) { + case ControllerSettingsStruct::CONTROLLER_USE_DNS: { byte choice = ControllerSettings.UseDNS; String options[2]; @@ -96,58 +102,63 @@ void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettin addFormSelector(displayName, internalName, 2, options, NULL, NULL, choice, true); break; } - case CONTROLLER_HOSTNAME: + case ControllerSettingsStruct::CONTROLLER_HOSTNAME: { addFormTextBox(displayName, internalName, ControllerSettings.HostName, sizeof(ControllerSettings.HostName) - 1); break; } - case CONTROLLER_IP: + case ControllerSettingsStruct::CONTROLLER_IP: { addFormIPBox(displayName, internalName, ControllerSettings.IP); break; } - case CONTROLLER_PORT: + case ControllerSettingsStruct::CONTROLLER_PORT: { addFormNumericBox(displayName, internalName, ControllerSettings.Port, 1, 65535); break; } - case CONTROLLER_USER: + case ControllerSettingsStruct::CONTROLLER_USER: { + size_t fieldMaxLength = ControllerSettings.useExtendedCredentials() ? EXT_SECURITY_MAX_USER_LENGTH : sizeof(SecuritySettings.ControllerUser[0]) - 1; addFormTextBox(displayName, internalName, - SecuritySettings.ControllerUser[controllerindex], - sizeof(SecuritySettings.ControllerUser[0]) - 1); + getControllerUser(controllerindex, ControllerSettings), + fieldMaxLength); break; } - case CONTROLLER_PASS: + case ControllerSettingsStruct::CONTROLLER_PASS: { + size_t fieldMaxLength = ControllerSettings.useExtendedCredentials() ? EXT_SECURITY_MAX_PASS_LENGTH : sizeof(SecuritySettings.ControllerPassword[0]) - 1; if (isAlternativeDisplayName) { // It is not a regular password, thus use normal text field. - addFormTextBox(displayName, internalName, SecuritySettings.ControllerPassword[controllerindex], - sizeof(SecuritySettings.ControllerPassword[0]) - 1); + addFormTextBox(displayName, internalName, + getControllerPass(controllerindex, ControllerSettings), + fieldMaxLength); } else { - addFormPasswordBox(displayName, internalName, SecuritySettings.ControllerPassword[controllerindex], - sizeof(SecuritySettings.ControllerPassword[0]) - 1); + addFormPasswordBox(displayName, internalName, + getControllerPass(controllerindex, ControllerSettings), + fieldMaxLength); + } break; } - case CONTROLLER_MIN_SEND_INTERVAL: + case ControllerSettingsStruct::CONTROLLER_MIN_SEND_INTERVAL: { addFormNumericBox(displayName, internalName, ControllerSettings.MinimalTimeBetweenMessages, 1, CONTROLLER_DELAY_QUEUE_DELAY_MAX); addUnit(F("ms")); break; } - case CONTROLLER_MAX_QUEUE_DEPTH: + case ControllerSettingsStruct::CONTROLLER_MAX_QUEUE_DEPTH: { addFormNumericBox(displayName, internalName, ControllerSettings.MaxQueueDepth, 1, CONTROLLER_DELAY_QUEUE_DEPTH_MAX); break; } - case CONTROLLER_MAX_RETRIES: + case ControllerSettingsStruct::CONTROLLER_MAX_RETRIES: { addFormNumericBox(displayName, internalName, ControllerSettings.MaxRetry, 1, CONTROLLER_DELAY_QUEUE_RETRY_MAX); break; } - case CONTROLLER_FULL_QUEUE_ACTION: + case ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION: { String options[2]; options[0] = F("Ignore New"); @@ -155,7 +166,7 @@ void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettin addFormSelector(displayName, internalName, 2, options, NULL, NULL, ControllerSettings.DeleteOldest, false); break; } - case CONTROLLER_CHECK_REPLY: + case ControllerSettingsStruct::CONTROLLER_CHECK_REPLY: { String options[2]; options[0] = F("Ignore Acknowledgement"); @@ -163,53 +174,65 @@ void addControllerParameterForm(const ControllerSettingsStruct& ControllerSettin addFormSelector(displayName, internalName, 2, options, NULL, NULL, ControllerSettings.MustCheckReply, false); break; } - case CONTROLLER_SUBSCRIBE: + case ControllerSettingsStruct::CONTROLLER_CLIENT_ID: + addFormTextBox(displayName, internalName, ControllerSettings.ClientID, sizeof(ControllerSettings.ClientID) - 1); + break; + case ControllerSettingsStruct::CONTROLLER_UNIQUE_CLIENT_ID_RECONNECT: + addFormCheckBox(displayName, internalName, ControllerSettings.mqtt_uniqueMQTTclientIdReconnect()); + break; + case ControllerSettingsStruct::CONTROLLER_RETAINFLAG: + addFormCheckBox(displayName, internalName, ControllerSettings.mqtt_retainFlag()); + break; + case ControllerSettingsStruct::CONTROLLER_SUBSCRIBE: addFormTextBox(displayName, internalName, ControllerSettings.Subscribe, sizeof(ControllerSettings.Subscribe) - 1); break; - case CONTROLLER_PUBLISH: + case ControllerSettingsStruct::CONTROLLER_PUBLISH: addFormTextBox(displayName, internalName, ControllerSettings.Publish, sizeof(ControllerSettings.Publish) - 1); break; - case CONTROLLER_LWT_TOPIC: + case ControllerSettingsStruct::CONTROLLER_LWT_TOPIC: addFormTextBox(displayName, internalName, ControllerSettings.MQTTLwtTopic, sizeof(ControllerSettings.MQTTLwtTopic) - 1); break; - case CONTROLLER_LWT_CONNECT_MESSAGE: + case ControllerSettingsStruct::CONTROLLER_LWT_CONNECT_MESSAGE: addFormTextBox(displayName, internalName, ControllerSettings.LWTMessageConnect, sizeof(ControllerSettings.LWTMessageConnect) - 1); break; - case CONTROLLER_LWT_DISCONNECT_MESSAGE: + case ControllerSettingsStruct::CONTROLLER_LWT_DISCONNECT_MESSAGE: addFormTextBox(displayName, internalName, ControllerSettings.LWTMessageDisconnect, sizeof(ControllerSettings.LWTMessageDisconnect) - 1); break; - case CONTROLLER_SEND_LWT: + case ControllerSettingsStruct::CONTROLLER_SEND_LWT: addFormCheckBox(displayName, internalName, ControllerSettings.mqtt_sendLWT()); break; - case CONTROLLER_WILL_RETAIN: + case ControllerSettingsStruct::CONTROLLER_WILL_RETAIN: addFormCheckBox(displayName, internalName, ControllerSettings.mqtt_willRetain()); break; - case CONTROLLER_CLEAN_SESSION: + case ControllerSettingsStruct::CONTROLLER_CLEAN_SESSION: addFormCheckBox(displayName, internalName, ControllerSettings.mqtt_cleanSession()); break; - case CONTROLLER_TIMEOUT: + case ControllerSettingsStruct::CONTROLLER_USE_EXTENDED_CREDENTIALS: + addFormCheckBox(displayName, internalName, ControllerSettings.useExtendedCredentials()); + break; + case ControllerSettingsStruct::CONTROLLER_TIMEOUT: addFormNumericBox(displayName, internalName, ControllerSettings.ClientTimeout, 10, CONTROLLER_CLIENTTIMEOUT_MAX); addUnit(F("ms")); break; - case CONTROLLER_SAMPLE_SET_INITIATOR: + case ControllerSettingsStruct::CONTROLLER_SAMPLE_SET_INITIATOR: addTaskSelectBox(displayName, internalName, ControllerSettings.SampleSetInitiator); break; - case CONTROLLER_ENABLED: + case ControllerSettingsStruct::CONTROLLER_ENABLED: addFormCheckBox(displayName, internalName, Settings.ControllerEnabled[controllerindex]); break; } } -void saveControllerParameterForm(ControllerSettingsStruct& ControllerSettings, byte controllerindex, byte parameterIdx) { - byte ProtocolIndex = getProtocolIndex_from_ControllerIndex(controllerindex); +void saveControllerParameterForm(ControllerSettingsStruct& ControllerSettings, controllerIndex_t controllerindex, ControllerSettingsStruct::VarType varType) { + protocolIndex_t ProtocolIndex = getProtocolIndex_from_ControllerIndex(controllerindex); if (!validProtocolIndex(ProtocolIndex)) { return; } - String internalName = getControllerParameterInternalName(ProtocolIndex, parameterIdx); + String internalName = getControllerParameterInternalName(ProtocolIndex, varType); - switch (parameterIdx) { - case CONTROLLER_USE_DNS: ControllerSettings.UseDNS = getFormItemInt(internalName); break; - case CONTROLLER_HOSTNAME: + switch (varType) { + case ControllerSettingsStruct::CONTROLLER_USE_DNS: ControllerSettings.UseDNS = getFormItemInt(internalName); break; + case ControllerSettingsStruct::CONTROLLER_HOSTNAME: if (ControllerSettings.UseDNS) { @@ -222,7 +245,7 @@ void saveControllerParameterForm(ControllerSettingsStruct& ControllerSettings, b } } break; - case CONTROLLER_IP: + case ControllerSettingsStruct::CONTROLLER_IP: if (!ControllerSettings.UseDNS) { @@ -230,63 +253,75 @@ void saveControllerParameterForm(ControllerSettingsStruct& ControllerSettings, b str2ip(controllerip, ControllerSettings.IP); } break; - case CONTROLLER_PORT: + case ControllerSettingsStruct::CONTROLLER_PORT: ControllerSettings.Port = getFormItemInt(internalName, ControllerSettings.Port); break; - case CONTROLLER_USER: - strncpy_webserver_arg(SecuritySettings.ControllerUser[controllerindex], internalName); + case ControllerSettingsStruct::CONTROLLER_USER: + setControllerUser(controllerindex, ControllerSettings, web_server.arg(internalName)); break; - case CONTROLLER_PASS: - copyFormPassword(internalName, SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0])); + case ControllerSettingsStruct::CONTROLLER_PASS: + setControllerPass(controllerindex, ControllerSettings, web_server.arg(internalName)); break; - case CONTROLLER_MIN_SEND_INTERVAL: + case ControllerSettingsStruct::CONTROLLER_MIN_SEND_INTERVAL: ControllerSettings.MinimalTimeBetweenMessages = getFormItemInt(internalName, ControllerSettings.MinimalTimeBetweenMessages); break; - case CONTROLLER_MAX_QUEUE_DEPTH: + case ControllerSettingsStruct::CONTROLLER_MAX_QUEUE_DEPTH: ControllerSettings.MaxQueueDepth = getFormItemInt(internalName, ControllerSettings.MaxQueueDepth); break; - case CONTROLLER_MAX_RETRIES: + case ControllerSettingsStruct::CONTROLLER_MAX_RETRIES: ControllerSettings.MaxRetry = getFormItemInt(internalName, ControllerSettings.MaxRetry); break; - case CONTROLLER_FULL_QUEUE_ACTION: + case ControllerSettingsStruct::CONTROLLER_FULL_QUEUE_ACTION: ControllerSettings.DeleteOldest = getFormItemInt(internalName, ControllerSettings.DeleteOldest); break; - case CONTROLLER_CHECK_REPLY: + case ControllerSettingsStruct::CONTROLLER_CHECK_REPLY: ControllerSettings.MustCheckReply = getFormItemInt(internalName, ControllerSettings.MustCheckReply); break; - case CONTROLLER_SUBSCRIBE: + case ControllerSettingsStruct::CONTROLLER_CLIENT_ID: + strncpy_webserver_arg(ControllerSettings.ClientID, internalName); + break; + case ControllerSettingsStruct::CONTROLLER_UNIQUE_CLIENT_ID_RECONNECT: + ControllerSettings.mqtt_uniqueMQTTclientIdReconnect(isFormItemChecked(internalName)); + break; + case ControllerSettingsStruct::CONTROLLER_RETAINFLAG: + ControllerSettings.mqtt_retainFlag(isFormItemChecked(internalName)); + break; + case ControllerSettingsStruct::CONTROLLER_SUBSCRIBE: strncpy_webserver_arg(ControllerSettings.Subscribe, internalName); break; - case CONTROLLER_PUBLISH: + case ControllerSettingsStruct::CONTROLLER_PUBLISH: strncpy_webserver_arg(ControllerSettings.Publish, internalName); break; - case CONTROLLER_LWT_TOPIC: + case ControllerSettingsStruct::CONTROLLER_LWT_TOPIC: strncpy_webserver_arg(ControllerSettings.MQTTLwtTopic, internalName); break; - case CONTROLLER_LWT_CONNECT_MESSAGE: + case ControllerSettingsStruct::CONTROLLER_LWT_CONNECT_MESSAGE: strncpy_webserver_arg(ControllerSettings.LWTMessageConnect, internalName); break; - case CONTROLLER_LWT_DISCONNECT_MESSAGE: + case ControllerSettingsStruct::CONTROLLER_LWT_DISCONNECT_MESSAGE: strncpy_webserver_arg(ControllerSettings.LWTMessageDisconnect, internalName); break; - case CONTROLLER_SEND_LWT: + case ControllerSettingsStruct::CONTROLLER_SEND_LWT: ControllerSettings.mqtt_sendLWT(isFormItemChecked(internalName)); break; - case CONTROLLER_WILL_RETAIN: + case ControllerSettingsStruct::CONTROLLER_WILL_RETAIN: ControllerSettings.mqtt_willRetain(isFormItemChecked(internalName)); break; - case CONTROLLER_CLEAN_SESSION: + case ControllerSettingsStruct::CONTROLLER_CLEAN_SESSION: ControllerSettings.mqtt_cleanSession(isFormItemChecked(internalName)); break; - case CONTROLLER_TIMEOUT: + case ControllerSettingsStruct::CONTROLLER_USE_EXTENDED_CREDENTIALS: + ControllerSettings.useExtendedCredentials(isFormItemChecked(internalName)); + break; + case ControllerSettingsStruct::CONTROLLER_TIMEOUT: ControllerSettings.ClientTimeout = getFormItemInt(internalName, ControllerSettings.ClientTimeout); break; - case CONTROLLER_SAMPLE_SET_INITIATOR: + case ControllerSettingsStruct::CONTROLLER_SAMPLE_SET_INITIATOR: ControllerSettings.SampleSetInitiator = getFormItemInt(internalName, ControllerSettings.SampleSetInitiator); break; - case CONTROLLER_ENABLED: + case ControllerSettingsStruct::CONTROLLER_ENABLED: Settings.ControllerEnabled[controllerindex] = isFormItemChecked(internalName); break; } diff --git a/src/_P003_Pulse.ino b/src/_P003_Pulse.ino index 67e6bd324..0a49d3b73 100644 --- a/src/_P003_Pulse.ino +++ b/src/_P003_Pulse.ino @@ -133,43 +133,17 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string) case PLUGIN_INIT: { - String log = F("INIT : Pulse "); - log += Settings.TaskDevicePin1[event->TaskIndex]; - addLog(LOG_LEVEL_INFO,log); - pinMode(Settings.TaskDevicePin1[event->TaskIndex], INPUT_PULLUP); - success = Plugin_003_pulseinit(Settings.TaskDevicePin1[event->TaskIndex], event->TaskIndex,Settings.TaskDevicePluginConfig[event->TaskIndex][2]); - + // Restore any value that may have been read from the RTC. Plugin_003_pulseCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; Plugin_003_pulseTotalCounter[event->TaskIndex] = UserVar[event->BaseVarIndex+1]; Plugin_003_pulseTime[event->TaskIndex] = UserVar[event->BaseVarIndex+2]; - switch (Settings.TaskDevicePluginConfig[event->TaskIndex][1]) - { - case 0: - { - Plugin_003_pulseCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; - break; - } - case 1: - { - Plugin_003_pulseCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; - Plugin_003_pulseTotalCounter[event->TaskIndex] = UserVar[event->BaseVarIndex+1]; - Plugin_003_pulseTime[event->TaskIndex] = UserVar[event->BaseVarIndex+2]; - break; - } - case 2: - { - Plugin_003_pulseTotalCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; - break; - } - case 3: - { - Plugin_003_pulseCounter[event->TaskIndex] = UserVar[event->BaseVarIndex]; - Plugin_003_pulseTotalCounter[event->TaskIndex] = UserVar[event->BaseVarIndex+1]; - break; - } - } + String log = F("INIT : Pulse "); + log += Settings.TaskDevicePin1[event->TaskIndex]; + addLog(LOG_LEVEL_INFO,log); + pinMode(Settings.TaskDevicePin1[event->TaskIndex], INPUT_PULLUP); + success = Plugin_003_pulseinit(Settings.TaskDevicePin1[event->TaskIndex], event->TaskIndex,Settings.TaskDevicePluginConfig[event->TaskIndex][2]); break; } diff --git a/src/_P036_FrameOLED.ino b/src/_P036_FrameOLED.ino index 03b6503ff..1535d3b75 100644 --- a/src/_P036_FrameOLED.ino +++ b/src/_P036_FrameOLED.ino @@ -12,6 +12,8 @@ // Added to the main repository with some optimizations and some limitations. // Al long as the device is not selected, no RAM is waisted. // +// @tonhuisman: 2020-03-05 +// CHG: Added setting for 'Wake display on receiving text', when unticked doesn't enable the display if it is off by time-out // @uwekaditz: 2019-11-22 // CHG: Each line can now have 64 characters (version is saved as Bit23-20 in PCONFIG_LONG(0))) // FIX: Overlapping while page scrolling (size of line content for scrolling pages limited to 128 pixel) @@ -82,6 +84,7 @@ static int8_t lastWiFiState = P36_WIFI_STATE_UNSET; static uint8_t OLEDIndex = 0; static boolean bPin3Invers; static boolean bScrollLines; +static boolean bNoDisplayOnReceivedText; static boolean bAlternativHeader = false; static uint16_t HeaderCount = 0; static boolean bPageScrollDisabled = true; // first page after INIT without scrolling @@ -378,6 +381,10 @@ boolean Plugin_036(uint8_t function, struct EventStruct *event, String& string) bScrollLines = getBitFromUL(PCONFIG_LONG(0), 17); // Bit 17 addFormCheckBox(F("Scroll long lines"), F("p036_ScrollLines"), bScrollLines); + bNoDisplayOnReceivedText = getBitFromUL(PCONFIG_LONG(0), 18); // Bit 18 + addFormCheckBox(F("Wake display on receiving text"), F("p036_NoDisplay"), !bNoDisplayOnReceivedText); + addFormNote(F("When checked, the display wakes up at receiving remote updates.")); + for (uint8_t varNr = 0; varNr < P36_Nlines; varNr++) { addFormTextBox(String(F("Line ")) + (varNr + 1), getPluginCustomArgName(varNr), String(P036_DisplayLinesV1[varNr].Content), P36_NcharsV1-1); @@ -409,6 +416,7 @@ boolean Plugin_036(uint8_t function, struct EventStruct *event, String& string) set8BitToUL(lSettings, 0, uint8_t(getFormItemInt(F("p036_headerAlternate")) & 0xff)); // Bit 7-0 HeaderContentAlternative P036_setBitToUL(lSettings, 16, isFormItemChecked(F("p036_pin3invers"))); // Bit 16 Pin3Invers P036_setBitToUL(lSettings, 17, isFormItemChecked(F("p036_ScrollLines"))); // Bit 17 ScrollLines + P036_setBitToUL(lSettings, 18, !isFormItemChecked(F("p036_NoDisplay"))); // Bit 18 NoDisplayOnReceivingText // save CustomTaskSettings always in version V1 set4BitToUL(lSettings, 20, 0x01); // Bit23-20 Version CustomTaskSettings -> version V1 @@ -753,9 +761,11 @@ boolean Plugin_036(uint8_t function, struct EventStruct *event, String& string) } nextFrameToDisplay = LineNo / ScrollingPages.linesPerFrame; // next frame shows the new content - displayTimer = PCONFIG(4); - if (UserVar[event->BaseVarIndex] == 0) { + + bNoDisplayOnReceivedText = getBitFromUL(PCONFIG_LONG(0), 18); // Bit 18 NoDisplayOnReceivedText + if (UserVar[event->BaseVarIndex] == 0 && !bNoDisplayOnReceivedText) { // display was OFF, turn it ON + displayTimer = PCONFIG(4); display->displayOn(); UserVar[event->BaseVarIndex] = 1; // Save the fact that the display is now ON } diff --git a/src/_P037_MQTTImport.ino b/src/_P037_MQTTImport.ino index 80b99bd42..594ca60ab 100644 --- a/src/_P037_MQTTImport.ino +++ b/src/_P037_MQTTImport.ino @@ -437,8 +437,10 @@ boolean MQTTConnect_037() { String log = ""; - if ((SecuritySettings.ControllerUser[enabledMqttController][0] != 0) && (SecuritySettings.ControllerPassword[enabledMqttController][0] != 0)) - result = MQTTclient_037->connect(clientid.c_str(), SecuritySettings.ControllerUser[enabledMqttController], SecuritySettings.ControllerPassword[enabledMqttController]); + if (hasControllerCredentialsSet(enabledMqttController, ControllerSettings)) + result = MQTTclient_037->connect(clientid.c_str(), + getControllerUser(enabledMqttController, ControllerSettings).c_str(), + getControllerPass(enabledMqttController, ControllerSettings).c_str()); else result = MQTTclient_037->connect(clientid.c_str()); diff --git a/src/src/Commands/Diagnostic.cpp b/src/src/Commands/Diagnostic.cpp index 483f2b1d3..81454c9b0 100644 --- a/src/src/Commands/Diagnostic.cpp +++ b/src/src/Commands/Diagnostic.cpp @@ -5,9 +5,10 @@ #include "../../ESPEasy_common.h" #include "../../ESPEasy_fdwdecl.h" #include "../DataStructs/ESPEasy_EventStruct.h" - #include "../DataStructs/SettingsType.h" */ +#include "../DataStructs/SettingsType.h" + #include #include @@ -93,18 +94,18 @@ String Command_MemInfo_detail(struct EventStruct *event, const char *Line) #endif // ifndef BUILD_MINIMAL_OTA Command_MemInfo(event, Line); - for (int st = 0; st < SettingsType_MAX; ++st) { - SettingsType settingsType = static_cast(st); + for (int st = 0; st < SettingsType::SettingsType_MAX; ++st) { + SettingsType::SettingsType::Enum settingsType = static_cast(st); int max_index, offset, max_size; int struct_size = 0; serialPrintln(); - serialPrint(getSettingsTypeString(settingsType)); + serialPrint(SettingsType::getSettingsTypeString(settingsType)); serialPrintln(F(" | start | end | max_size | struct_size")); serialPrintln(F("--- | --- | --- | --- | ---")); - getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); + SettingsType::getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); for (int i = 0; i < max_index; ++i) { - getSettingsParameters(settingsType, i, offset, max_size); + SettingsType::getSettingsParameters(settingsType, i, offset, max_size); serialPrint(String(i)); serialPrint("|"); serialPrint(String(offset)); diff --git a/src/src/Commands/MQTT.cpp b/src/src/Commands/MQTT.cpp index a61c522e1..321fb15da 100644 --- a/src/src/Commands/MQTT.cpp +++ b/src/src/Commands/MQTT.cpp @@ -14,36 +14,6 @@ #include "../../ESPEasy_Log.h" -String Command_MQTT_Retain(struct EventStruct *event, const char *Line) -{ - return Command_GetORSetBool(event, F("MQTT Retain:"), - Line, - (bool *)&Settings.MQTTRetainFlag, - 1); -} - -String Command_MQTT_UseUnitNameAsClientId(struct EventStruct *event, const char *Line) -{ - return Command_GetORSetBool(event, F("MQTT Use Unit Name as ClientId:"), - Line, - (bool *)&Settings.MQTTUseUnitNameAsClientId, - 1); -} - -String Command_MQTT_messageDelay(struct EventStruct *event, const char *Line) -{ - if (HasArgv(Line, 2)) { - Settings.MessageDelay = event->Par1; - } - else { - String result = F("MQTT message delay:"); - result += Settings.MessageDelay; - serialPrintln(); - serialPrintln(result); - return result; - } - return return_command_success(); -} String Command_MQTT_Publish(struct EventStruct *event, const char *Line) { @@ -60,6 +30,10 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line) addLog(LOG_LEVEL_DEBUG, String(F("Publish: ")) + topic + value); if ((topic.length() > 0) && (value.length() > 0)) { + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(enabledMqttController, ControllerSettings); + + // @giig1967g: if payload starts with '=' then treat it as a Formula and evaluate accordingly // The evaluated value is already present in event->Par2 // FIXME TD-er: Is the evaluated value always present in event->Par2 ? @@ -67,10 +41,10 @@ String Command_MQTT_Publish(struct EventStruct *event, const char *Line) bool success = false; if (value[0] != '=') { - success = MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), Settings.MQTTRetainFlag); + success = MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), ControllerSettings.mqtt_retainFlag()); } else { - success = MQTTpublish(enabledMqttController, topic.c_str(), String(event->Par2).c_str(), Settings.MQTTRetainFlag); + success = MQTTpublish(enabledMqttController, topic.c_str(), String(event->Par2).c_str(), ControllerSettings.mqtt_retainFlag()); } if (success) { return return_command_success(); @@ -98,9 +72,12 @@ String Command_MQTT_Subscribe(struct EventStruct *event, const char* Line) // ToDo TD-er: Not sure about this function, but at least it sends to an existing MQTTclient controllerIndex_t enabledMqttController = firstEnabledMQTT_ControllerIndex(); if (validControllerIndex(enabledMqttController)) { + MakeControllerSettings(ControllerSettings); + LoadControllerSettings(enabledMqttController, ControllerSettings); + String eventName = Line; String topic = eventName.substring(10); - if (!MQTTsubscribe(enabledMqttController, topic.c_str(), Settings.MQTTRetainFlag)) + if (!MQTTsubscribe(enabledMqttController, topic.c_str(), ControllerSettings.mqtt_retainFlag())) return_command_failed(); return_command_success(); } diff --git a/src/src/Commands/MQTT.h b/src/src/Commands/MQTT.h index f29eab6a8..1b5c64002 100644 --- a/src/src/Commands/MQTT.h +++ b/src/src/Commands/MQTT.h @@ -5,14 +5,6 @@ class String; -String Command_MQTT_Retain(struct EventStruct *event, - const char *Line); - -// FIXME TD-er: Command never called. -String Command_MQTT_UseUnitNameAsClientId(struct EventStruct *event, - const char *Line); -String Command_MQTT_messageDelay(struct EventStruct *event, - const char *Line); String Command_MQTT_Publish(struct EventStruct *event, const char *Line); diff --git a/src/src/Commands/System.cpp b/src/src/Commands/System.cpp index 4cb532604..f3214a374 100644 --- a/src/src/Commands/System.cpp +++ b/src/src/Commands/System.cpp @@ -17,7 +17,7 @@ String Command_System_NoSleep(struct EventStruct *event, const char* Line) String Command_System_deepSleep(struct EventStruct *event, const char* Line) { - if (event->Par1 > 0) { + if (event->Par1 >= 0) { deepSleepStart(event->Par1); // call the second part of the function to avoid check and enable one-shot operation } return return_command_success(); diff --git a/src/src/DataStructs/ControllerSettingsStruct.cpp b/src/src/DataStructs/ControllerSettingsStruct.cpp index 8c780ed09..8036aec50 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.cpp +++ b/src/src/DataStructs/ControllerSettingsStruct.cpp @@ -31,11 +31,13 @@ void ControllerSettingsStruct::reset() { IP[i] = 0; } ZERO_FILL(HostName); + ZERO_FILL(ClientID); ZERO_FILL(Publish); ZERO_FILL(Subscribe); ZERO_FILL(MQTTLwtTopic); ZERO_FILL(LWTMessageConnect); ZERO_FILL(LWTMessageDisconnect); + safe_strncpy(ClientID, F(CONTROLLER_DEFAULT_CLIENTID), sizeof(ClientID)); } void ControllerSettingsStruct::validate() { @@ -176,8 +178,7 @@ bool ControllerSettingsStruct::updateIPcache() { return false; } - -bool ControllerSettingsStruct::mqtt_cleanSession() const +bool ControllerSettingsStruct::mqtt_cleanSession() const { return getBitFromUL(MQTT_flags, 1); } @@ -197,7 +198,7 @@ void ControllerSettingsStruct::mqtt_sendLWT(bool value) setBitToUL(MQTT_flags, 2, !value); } -bool ControllerSettingsStruct::mqtt_willRetain() const +bool ControllerSettingsStruct::mqtt_willRetain() const { return !getBitFromUL(MQTT_flags, 3); } @@ -206,3 +207,33 @@ void ControllerSettingsStruct::mqtt_willRetain(bool value) { setBitToUL(MQTT_flags, 3, !value); } + +bool ControllerSettingsStruct::mqtt_uniqueMQTTclientIdReconnect() const +{ + return getBitFromUL(MQTT_flags, 4); +} + +void ControllerSettingsStruct::mqtt_uniqueMQTTclientIdReconnect(bool value) +{ + setBitToUL(MQTT_flags, 4, value); +} + +bool ControllerSettingsStruct::mqtt_retainFlag() const +{ + return getBitFromUL(MQTT_flags, 5); +} + +void ControllerSettingsStruct::mqtt_retainFlag(bool value) +{ + setBitToUL(MQTT_flags, 5, value); +} + +bool ControllerSettingsStruct::useExtendedCredentials() const +{ + return getBitFromUL(MQTT_flags, 6); +} + +void ControllerSettingsStruct::useExtendedCredentials(bool value) +{ + setBitToUL(MQTT_flags, 6, value); +} diff --git a/src/src/DataStructs/ControllerSettingsStruct.h b/src/src/DataStructs/ControllerSettingsStruct.h index 43d8a6aea..67f27f208 100644 --- a/src/src/DataStructs/ControllerSettingsStruct.h +++ b/src/src/DataStructs/ControllerSettingsStruct.h @@ -47,36 +47,47 @@ class WiFiUDP; # define CONTROLLER_CLIENTTIMEOUT_DFLT 100 #endif // ifndef CONTROLLER_CLIENTTIMEOUT_DFLT - -// ******************************************************************************** -// IDs of controller settings, used to generate web forms -// ******************************************************************************** - -#define CONTROLLER_USE_DNS 1 -#define CONTROLLER_HOSTNAME 2 -#define CONTROLLER_IP 3 -#define CONTROLLER_PORT 4 -#define CONTROLLER_USER 5 -#define CONTROLLER_PASS 6 -#define CONTROLLER_MIN_SEND_INTERVAL 7 -#define CONTROLLER_MAX_QUEUE_DEPTH 8 -#define CONTROLLER_MAX_RETRIES 9 -#define CONTROLLER_FULL_QUEUE_ACTION 10 -#define CONTROLLER_CHECK_REPLY 12 -#define CONTROLLER_SUBSCRIBE 13 -#define CONTROLLER_PUBLISH 14 -#define CONTROLLER_LWT_TOPIC 15 -#define CONTROLLER_LWT_CONNECT_MESSAGE 16 -#define CONTROLLER_LWT_DISCONNECT_MESSAGE 17 -#define CONTROLLER_SEND_LWT 18 -#define CONTROLLER_WILL_RETAIN 19 -#define CONTROLLER_CLEAN_SESSION 20 -#define CONTROLLER_TIMEOUT 21 -#define CONTROLLER_SAMPLE_SET_INITIATOR 22 -#define CONTROLLER_ENABLED 23 // Keep this as last, is used to loop over all parameters +#ifndef CONTROLLER_DEFAULT_CLIENTID +# define CONTROLLER_DEFAULT_CLIENTID "%sysname%_%unit%" +#endif // ifndef CONTROLLER_DEFAULT_CLIENTID struct ControllerSettingsStruct { + // ******************************************************************************** + // IDs of controller settings, used to generate web forms + // ******************************************************************************** + enum VarType { + CONTROLLER_USE_DNS = 0, // PLace this before HOSTNAME/IP + CONTROLLER_USE_EXTENDED_CREDENTIALS = 1, // Place this before USER/PASS + CONTROLLER_HOSTNAME, + CONTROLLER_IP, + CONTROLLER_PORT, + CONTROLLER_USER, + CONTROLLER_PASS, + CONTROLLER_MIN_SEND_INTERVAL, + CONTROLLER_MAX_QUEUE_DEPTH, + CONTROLLER_MAX_RETRIES, + CONTROLLER_FULL_QUEUE_ACTION, + CONTROLLER_CHECK_REPLY, + CONTROLLER_CLIENT_ID, + CONTROLLER_UNIQUE_CLIENT_ID_RECONNECT, + CONTROLLER_RETAINFLAG, + CONTROLLER_SUBSCRIBE, + CONTROLLER_PUBLISH, + CONTROLLER_LWT_TOPIC, + CONTROLLER_LWT_CONNECT_MESSAGE, + CONTROLLER_LWT_DISCONNECT_MESSAGE, + CONTROLLER_SEND_LWT, + CONTROLLER_WILL_RETAIN, + CONTROLLER_CLEAN_SESSION, + CONTROLLER_TIMEOUT, + CONTROLLER_SAMPLE_SET_INITIATOR, + + // Keep this as last, is used to loop over all parameters + CONTROLLER_ENABLED + }; + + ControllerSettingsStruct(); void reset(); @@ -99,14 +110,23 @@ struct ControllerSettingsStruct String getHostPortString() const; // MQTT_flags defaults to 0, keep in mind when adding bit lookups. - bool mqtt_cleanSession() const; - void mqtt_cleanSession(bool value); + bool mqtt_cleanSession() const; + void mqtt_cleanSession(bool value); - bool mqtt_sendLWT() const; - void mqtt_sendLWT(bool value); + bool mqtt_sendLWT() const; + void mqtt_sendLWT(bool value); - bool mqtt_willRetain() const; - void mqtt_willRetain(bool value); + bool mqtt_willRetain() const; + void mqtt_willRetain(bool value); + + bool mqtt_uniqueMQTTclientIdReconnect() const; + void mqtt_uniqueMQTTclientIdReconnect(bool value); + + bool mqtt_retainFlag() const; + void mqtt_retainFlag(bool value); + + bool useExtendedCredentials() const; + void useExtendedCredentials(bool value); boolean UseDNS; byte IP[4]; @@ -125,6 +145,7 @@ struct ControllerSettingsStruct boolean MustCheckReply; // When set to false, a sent message is considered always successful. taskIndex_t SampleSetInitiator; // The first task to start a sample set. uint32_t MQTT_flags; // Various flags for MQTT controllers + char ClientID[65]; // Used to define the Client ID used by the controller private: diff --git a/src/src/DataStructs/ESPEasyDefaults.h b/src/src/DataStructs/ESPEasyDefaults.h index b1e9ed9f4..b2597308f 100644 --- a/src/src/DataStructs/ESPEasyDefaults.h +++ b/src/src/DataStructs/ESPEasyDefaults.h @@ -127,6 +127,10 @@ #ifndef DEFAULT_SERVER_USEDNS #define DEFAULT_SERVER_USEDNS false // true: Use hostname. false: use IP #endif +#ifndef DEFAULT_USE_EXTD_CONTROLLER_CREDENTIALS +#define DEFAULT_USE_EXTD_CONTROLLER_CREDENTIALS false // true: Allow longer user credentials for controllers +#endif + #ifndef DEFAULT_PORT #define DEFAULT_PORT 8080 // Enter your Server port value #endif diff --git a/src/src/DataStructs/ESPEasyLimits.h b/src/src/DataStructs/ESPEasyLimits.h index 5a5d7bf78..aeabf302a 100644 --- a/src/src/DataStructs/ESPEasyLimits.h +++ b/src/src/DataStructs/ESPEasyLimits.h @@ -125,6 +125,16 @@ #endif +// *********************************************************************** +// * Extended SecuritySettings +// *********************************************************************** +#ifndef EXT_SECURITY_MAX_USER_LENGTH + #define EXT_SECURITY_MAX_USER_LENGTH 128 +#endif +#ifndef EXT_SECURITY_MAX_PASS_LENGTH + #define EXT_SECURITY_MAX_PASS_LENGTH 128 +#endif + // *********************************************************************** // * Other operational limits // *********************************************************************** diff --git a/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp b/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp new file mode 100644 index 000000000..ae8cf62be --- /dev/null +++ b/src/src/DataStructs/ExtendedControllerCredentialsStruct.cpp @@ -0,0 +1,55 @@ +#include "ExtendedControllerCredentialsStruct.h" + +#include "../../ESPEasy_fdwdecl.h" + +#define EXT_CONTR_CRED_USER_OFFSET 0 +#define EXT_CONTR_CRED_PASS_OFFSET 1 + + +ExtendedControllerCredentialsStruct::ExtendedControllerCredentialsStruct() {} + + +String ExtendedControllerCredentialsStruct::load() +{ + return LoadStringArray(SettingsType::ExtdControllerCredentials_Type, + 0, + _strings, CONTROLLER_MAX * 2, 0); +} + +String ExtendedControllerCredentialsStruct::save() const +{ + return SaveStringArray(SettingsType::ExtdControllerCredentials_Type, + 0, + _strings, CONTROLLER_MAX * 2, 0); +} + + +String ExtendedControllerCredentialsStruct::getControllerUser(controllerIndex_t controller_idx) const +{ + if (validControllerIndex(controller_idx)) { + return _strings[controller_idx * 2 + EXT_CONTR_CRED_USER_OFFSET]; + } + return ""; +} + +String ExtendedControllerCredentialsStruct::getControllerPass(controllerIndex_t controller_idx) const +{ + if (validControllerIndex(controller_idx)) { + return _strings[controller_idx * 2 + EXT_CONTR_CRED_PASS_OFFSET]; + } + return ""; +} + +void ExtendedControllerCredentialsStruct::setControllerUser(controllerIndex_t controller_idx, const String& user) +{ + if (validControllerIndex(controller_idx)) { + _strings[controller_idx * 2 + EXT_CONTR_CRED_USER_OFFSET] = user; + } +} + +void ExtendedControllerCredentialsStruct::setControllerPass(controllerIndex_t controller_idx, const String& pass) +{ + if (validControllerIndex(controller_idx)) { + _strings[controller_idx * 2 + EXT_CONTR_CRED_PASS_OFFSET] = pass; + } +} diff --git a/src/src/DataStructs/ExtendedControllerCredentialsStruct.h b/src/src/DataStructs/ExtendedControllerCredentialsStruct.h new file mode 100644 index 000000000..b7ad084f0 --- /dev/null +++ b/src/src/DataStructs/ExtendedControllerCredentialsStruct.h @@ -0,0 +1,35 @@ +#ifndef DATASTRUCTS_EXTENDED_SECURITYSTRUCT_H +#define DATASTRUCTS_EXTENDED_SECURITYSTRUCT_H + +#include "../../ESPEasy_common.h" +#include "../DataStructs/ESPEasyLimits.h" +#include "../Globals/CPlugins.h" + + +/*********************************************************************************************\ + * Extended SecurityStruct +\*********************************************************************************************/ +struct ExtendedControllerCredentialsStruct +{ + ExtendedControllerCredentialsStruct(); + + String load(); + String save() const; + + String getControllerUser(controllerIndex_t controller_idx) const; + String getControllerPass(controllerIndex_t controller_idx) const; + + void setControllerUser(controllerIndex_t controller_idx, const String& user); + void setControllerPass(controllerIndex_t controller_idx, const String& pass); + + private: + + String _strings[CONTROLLER_MAX * 2]; + + + // TODO TD-er: Add extra WiFi credentials +}; + + + +#endif // DATASTRUCTS_EXTENDED_SECURITYSTRUCT_H \ No newline at end of file diff --git a/src/src/DataStructs/SettingsStruct.cpp b/src/src/DataStructs/SettingsStruct.cpp index 1cab7e24d..5ef1bc683 100644 --- a/src/src/DataStructs/SettingsStruct.cpp +++ b/src/src/DataStructs/SettingsStruct.cpp @@ -22,12 +22,12 @@ void SettingsStruct_tmpl::appendUnitToHostname(bool value) { } template -bool SettingsStruct_tmpl::uniqueMQTTclientIdReconnect() const { +bool SettingsStruct_tmpl::uniqueMQTTclientIdReconnect_unused() const { return getBitFromUL(VariousBits1, 2); } template -void SettingsStruct_tmpl::uniqueMQTTclientIdReconnect(bool value) { +void SettingsStruct_tmpl::uniqueMQTTclientIdReconnect_unused(bool value) { setBitToUL(VariousBits1, 2, value); } @@ -123,7 +123,8 @@ void SettingsStruct_tmpl::validate() { if (VariousBits1 > (1 << 30)) { VariousBits1 = 0; } ZERO_TERMINATE(Name); ZERO_TERMINATE(NTPHost); - if (I2C_clockSpeed == 0 || I2C_clockSpeed > 3400000) { I2C_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; } + + if ((I2C_clockSpeed == 0) || (I2C_clockSpeed > 3400000)) { I2C_clockSpeed = DEFAULT_I2C_CLOCK_SPEED; } } template @@ -207,29 +208,29 @@ void SettingsStruct_tmpl::clearMisc() { Pin_sd_cs = -1; for (byte i = 0; i < 17; ++i) { PinBootStates[i] = 0; } - BaudRate = 0; - MessageDelay = 0; - deepSleep_wakeTime = 0; - CustomCSS = false; - WDI2CAddress = 0; - UseRules = false; - UseSerial = true; - UseSSDP = false; - WireClockStretchLimit = 0; - I2C_clockSpeed = 400000; - GlobalSync = false; - ConnectionFailuresThreshold = 0; - MQTTRetainFlag = false; - InitSPI = false; - Pin_status_led_Inversed = false; - deepSleepOnFail = false; - UseValueLogger = false; - ArduinoOTAEnable = false; - UseRTOSMultitasking = false; - Pin_Reset = -1; - StructSize = sizeof(SettingsStruct_tmpl); - MQTTUseUnitNameAsClientId = 0; - VariousBits1 = 0; + BaudRate = 0; + MessageDelay_unused = 0; + deepSleep_wakeTime = 0; + CustomCSS = false; + WDI2CAddress = 0; + UseRules = false; + UseSerial = true; + UseSSDP = false; + WireClockStretchLimit = 0; + I2C_clockSpeed = 400000; + GlobalSync = false; + ConnectionFailuresThreshold = 0; + MQTTRetainFlag_unused = false; + InitSPI = false; + Pin_status_led_Inversed = false; + deepSleepOnFail = false; + UseValueLogger = false; + ArduinoOTAEnable = false; + UseRTOSMultitasking = false; + Pin_Reset = -1; + StructSize = sizeof(SettingsStruct_tmpl); + MQTTUseUnitNameAsClientId_unused = 0; + VariousBits1 = 0; OldRulesEngine(DEFAULT_RULES_OLDENGINE); ForceWiFi_bg_mode(DEFAULT_WIFI_FORCE_BG_MODE); WiFiRestart_connection_lost(DEFAULT_WIFI_RESTART_WIFI_CONN_LOST); @@ -295,9 +296,10 @@ String SettingsStruct_tmpl::getHostname() const { template String SettingsStruct_tmpl::getHostname(bool appendUnit) const { String hostname = this->Name; - if (this->Unit != 0 && appendUnit) { // only append non-zero unit number + + if ((this->Unit != 0) && appendUnit) { // only append non-zero unit number hostname += '_'; hostname += this->Unit; } return hostname; -} \ No newline at end of file +} diff --git a/src/src/DataStructs/SettingsStruct.h b/src/src/DataStructs/SettingsStruct.h index ab53d89ca..acec419a7 100644 --- a/src/src/DataStructs/SettingsStruct.h +++ b/src/src/DataStructs/SettingsStruct.h @@ -10,18 +10,19 @@ /*********************************************************************************************\ * SettingsStruct \*********************************************************************************************/ -template +template class SettingsStruct_tmpl { public: + SettingsStruct_tmpl(); // VariousBits1 defaults to 0, keep in mind when adding bit lookups. bool appendUnitToHostname() const; void appendUnitToHostname(bool value); - bool uniqueMQTTclientIdReconnect() const; - void uniqueMQTTclientIdReconnect(bool value); + bool uniqueMQTTclientIdReconnect_unused() const; + void uniqueMQTTclientIdReconnect_unused(bool value); bool OldRulesEngine() const; void OldRulesEngine(bool value); @@ -106,7 +107,7 @@ class SettingsStruct_tmpl byte WebLogLevel; byte SDLogLevel; unsigned long BaudRate; - unsigned long MessageDelay; + unsigned long MessageDelay_unused; // MQTT settings now moved to the controller settings. byte deepSleep_wakeTime; // 0 = Sleep Disabled, else time awake from sleep in seconds boolean CustomCSS; boolean DST; @@ -119,7 +120,7 @@ class SettingsStruct_tmpl boolean GlobalSync; unsigned long ConnectionFailuresThreshold; int16_t TimeZone; - boolean MQTTRetainFlag; + boolean MQTTRetainFlag_unused; boolean InitSPI; // FIXME TD-er: Must change to cpluginID_t, but then also another check must be added since changing the pluginID_t will also render settings incompatible byte Protocol[CONTROLLER_MAX]; @@ -160,7 +161,7 @@ class SettingsStruct_tmpl int8_t Pin_Reset; byte SyslogFacility; uint32_t StructSize; // Forced to be 32 bit, to make sure alignment is clear. - boolean MQTTUseUnitNameAsClientId; + boolean MQTTUseUnitNameAsClientId_unused; //its safe to extend this struct, up to several bytes, default values in config are 0 //look in misc.ino how config.dat is used because also other stuff is stored in it at different offsets. diff --git a/src/src/DataStructs/SettingsType.cpp b/src/src/DataStructs/SettingsType.cpp new file mode 100644 index 000000000..dfb66611e --- /dev/null +++ b/src/src/DataStructs/SettingsType.cpp @@ -0,0 +1,209 @@ +#include "SettingsType.h" + +#include "ControllerSettingsStruct.h" +#include "NotificationSettingsStruct.h" +#include "SecurityStruct.h" +#include "StorageLayout.h" +#include "../Globals/ExtraTaskSettings.h" +#include "../Globals/Settings.h" +#include "../../ESPEasy-Globals.h" + +String SettingsType::getSettingsTypeString(Enum settingsType) { + switch (settingsType) { + case BasicSettings_Type: return F("Settings"); + case TaskSettings_Type: return F("TaskSettings"); + case CustomTaskSettings_Type: return F("CustomTaskSettings"); + case ControllerSettings_Type: return F("ControllerSettings"); + case CustomControllerSettings_Type: return F("CustomControllerSettings"); + case NotificationSettings_Type: return F("NotificationSettings"); + case SecuritySettings_Type: return F("SecuritySettings"); + case ExtdControllerCredentials_Type: return F("ExtendedControllerCredentials"); + default: + break; + } + return ""; +} + +/********************************************************************************************\ + Offsets in settings files + \*********************************************************************************************/ +bool SettingsType::getSettingsParameters(Enum settingsType, int index, int& max_index, int& offset, int& max_size, int& struct_size) { + // The defined offsets should be used with () just in case they are the result of a formula in the defines. + struct_size = 0; + + switch (settingsType) { + case BasicSettings_Type: + { + max_index = 1; + offset = 0; + max_size = (DAT_BASIC_SETTINGS_SIZE); + struct_size = sizeof(SettingsStruct); + break; + } + case TaskSettings_Type: + { + max_index = TASKS_MAX; + offset = (DAT_OFFSET_TASKS) + (index * (DAT_TASKS_DISTANCE)); + max_size = DAT_TASKS_SIZE; + struct_size = sizeof(ExtraTaskSettingsStruct); + break; + } + case CustomTaskSettings_Type: + { + getSettingsParameters(TaskSettings_Type, index, max_index, offset, max_size, struct_size); + offset += (DAT_TASKS_CUSTOM_OFFSET); + max_size = DAT_TASKS_CUSTOM_SIZE; + + // struct_size may differ. + struct_size = 0; + break; + } + case ControllerSettings_Type: + { + max_index = CONTROLLER_MAX; + offset = (DAT_OFFSET_CONTROLLER) + (index * (DAT_CONTROLLER_SIZE)); + max_size = DAT_CONTROLLER_SIZE; + struct_size = sizeof(ControllerSettingsStruct); + break; + } + case CustomControllerSettings_Type: + { + max_index = CONTROLLER_MAX; + offset = (DAT_OFFSET_CUSTOM_CONTROLLER) + (index * (DAT_CUSTOM_CONTROLLER_SIZE)); + max_size = DAT_CUSTOM_CONTROLLER_SIZE; + + // struct_size may differ. + struct_size = 0; + break; + } + case NotificationSettings_Type: + { + max_index = NOTIFICATION_MAX; + offset = index * (DAT_NOTIFICATION_SIZE); + max_size = DAT_NOTIFICATION_SIZE; + struct_size = sizeof(NotificationSettingsStruct); + break; + } + case SecuritySettings_Type: + { + max_index = 1; + offset = 0; + max_size = DAT_SECURITYSETTINGS_SIZE; + struct_size = sizeof(SecurityStruct); + break; + } + case ExtdControllerCredentials_Type: + { + max_index = 1; + offset = DAT_EXTDCONTR_CRED_OFFSET; + max_size = DAT_EXTDCONTR_CRED_SIZE; + + // struct_size may differ. + struct_size = 0; + break; + } + case SettingsType_MAX: + { + max_index = -1; + offset = -1; + return false; + } + } + return index >= 0 && index < max_index; +} + +bool SettingsType::getSettingsParameters(Enum settingsType, int index, int& offset, int& max_size) { + int max_index = -1; + int struct_size; + + if (!getSettingsParameters(settingsType, index, max_index, offset, max_size, struct_size)) { + return false; + } + + if ((index >= 0) && (index < max_index)) { return true; } + offset = -1; + return false; +} + +int SettingsType::getMaxFilePos(Enum settingsType) { + int max_index, offset, max_size; + int struct_size = 0; + + getSettingsParameters(settingsType, 0, max_index, offset, max_size, struct_size); + getSettingsParameters(settingsType, max_index - 1, offset, max_size); + return offset + max_size - 1; +} + +int SettingsType::getFileSize(Enum settingsType) { + SettingsType::SettingsFileEnum file_type = SettingsType::getSettingsFile(settingsType); + int max_file_pos = 0; + + for (int st = 0; st < SettingsType_MAX; ++st) { + if (SettingsType::getSettingsFile(static_cast(st)) == file_type) { + int filePos = SettingsType::getMaxFilePos(static_cast(st)); + + if (filePos > max_file_pos) { + max_file_pos = filePos; + } + } + } + return max_file_pos; +} + +unsigned int SettingsType::getSVGcolor(Enum settingsType) { + switch (settingsType) { + case BasicSettings_Type: + return 0x5F0A87; + case TaskSettings_Type: + return 0xEE6352; + case CustomTaskSettings_Type: + return 0x59CD90; + case ControllerSettings_Type: + return 0x3FA7D6; + case CustomControllerSettings_Type: + return 0xFAC05E; + case NotificationSettings_Type: + return 0xF79D84; + + case SecuritySettings_Type: + return 0xff00a2; + case ExtdControllerCredentials_Type: + return 0xc300ff; + case SettingsType_MAX: + break; + } + return 0; +} + +SettingsType::SettingsFileEnum SettingsType::getSettingsFile(Enum settingsType) +{ + switch (settingsType) { + case BasicSettings_Type: + case TaskSettings_Type: + case CustomTaskSettings_Type: + case ControllerSettings_Type: + case CustomControllerSettings_Type: + return FILE_CONFIG_type; + case NotificationSettings_Type: + return FILE_NOTIFICATION_type; + case SecuritySettings_Type: + case ExtdControllerCredentials_Type: + return FILE_SECURITY_type; + + case SettingsType_MAX: + break; + } + return FILE_UNKNOWN_type; +} + +String SettingsType::getSettingsFileName(Enum settingsType) { + SettingsType::SettingsFileEnum file_type = getSettingsFile(settingsType); + + switch (file_type) { + case FILE_CONFIG_type: return F(FILE_CONFIG); + case FILE_NOTIFICATION_type: return F(FILE_NOTIFICATION); + case FILE_SECURITY_type: return F(FILE_SECURITY); + case FILE_UNKNOWN_type: break; + } + return ""; +} diff --git a/src/src/DataStructs/SettingsType.h b/src/src/DataStructs/SettingsType.h index 381e2ed49..361a80f83 100644 --- a/src/src/DataStructs/SettingsType.h +++ b/src/src/DataStructs/SettingsType.h @@ -3,20 +3,50 @@ #include "../../ESPEasy_common.h" -enum SettingsType { - BasicSettings_Type = 0, - TaskSettings_Type, - CustomTaskSettings_Type, - ControllerSettings_Type, - CustomControllerSettings_Type, - NotificationSettings_Type, - SettingsType_MAX +class SettingsType { +public: + enum Enum { + BasicSettings_Type = 0, + TaskSettings_Type, + CustomTaskSettings_Type, + ControllerSettings_Type, + CustomControllerSettings_Type, + NotificationSettings_Type, + SecuritySettings_Type, + ExtdControllerCredentials_Type, + + SettingsType_MAX + }; + + enum SettingsFileEnum { + FILE_CONFIG_type, + FILE_NOTIFICATION_type, + FILE_SECURITY_type, + FILE_UNKNOWN_type + }; + + static String getSettingsTypeString(Enum settingsType); + static bool getSettingsParameters(Enum settingsType, + int index, + int& offset, + int& max_size); + static bool getSettingsParameters(Enum settingsType, + int index, + int& max_index, + int& offset, + int& max_size, + int& struct_size); + + static int getMaxFilePos(Enum settingsType); + static int getFileSize(Enum settingsType); + + static unsigned int getSVGcolor(Enum settingsType); + + static SettingsFileEnum getSettingsFile(Enum settingsType); + static String getSettingsFileName(Enum settingsType); }; -String getSettingsTypeString(SettingsType settingsType); -bool getSettingsParameters(SettingsType settingsType, int index, int& offset, int& max_size); -bool getSettingsParameters(SettingsType settingsType, int index, int& max_index, int& offset, int& max_size, int& struct_size); -#endif // DATASTRUCTS_SETTINGSTYPE_H \ No newline at end of file +#endif // DATASTRUCTS_SETTINGSTYPE_H diff --git a/src/src/DataStructs/StorageLayout.h b/src/src/DataStructs/StorageLayout.h index c27789124..caf8bb754 100644 --- a/src/src/DataStructs/StorageLayout.h +++ b/src/src/DataStructs/StorageLayout.h @@ -83,6 +83,18 @@ # define DAT_NOTIFICATION_SIZE 1024 #endif // ifndef DAT_NOTIFICATION_SIZE +#ifndef DAT_SECURITYSETTINGS_SIZE +# define DAT_SECURITYSETTINGS_SIZE 1024 +#endif // ifndef DAT_SECURITYSETTINGS_SIZE + +#ifndef DAT_EXTDCONTR_CRED_OFFSET +# define DAT_EXTDCONTR_CRED_OFFSET 1024 // Equal to DAT_SECURITYSETTINGS_SIZE +#endif // ifndef DAT_EXTDCONTR_CRED_OFFSET + +#ifndef DAT_EXTDCONTR_CRED_SIZE +# define DAT_EXTDCONTR_CRED_SIZE 1024 +#endif // ifndef DAT_EXTDCONTR_CRED_SIZE + /* diff --git a/src/src/Globals/CPlugins.h b/src/src/Globals/CPlugins.h index 81086f124..28b79d9a5 100644 --- a/src/src/Globals/CPlugins.h +++ b/src/src/Globals/CPlugins.h @@ -4,6 +4,7 @@ #include #include #include "../DataStructs/ESPEasyLimits.h" +#include "../DataStructs/ControllerSettingsStruct.h" #include "../../ESPEasy_plugindefs.h" diff --git a/src/src/Globals/SecuritySettings.cpp b/src/src/Globals/SecuritySettings.cpp index 92db2d31a..3fd353f65 100644 --- a/src/src/Globals/SecuritySettings.cpp +++ b/src/src/Globals/SecuritySettings.cpp @@ -1,4 +1,5 @@ #include "../Globals/SecuritySettings.h" -SecurityStruct SecuritySettings; \ No newline at end of file +SecurityStruct SecuritySettings; +ExtendedControllerCredentialsStruct ExtendedControllerCredentials; \ No newline at end of file diff --git a/src/src/Globals/SecuritySettings.h b/src/src/Globals/SecuritySettings.h index 014e65758..7ef8b18c4 100644 --- a/src/src/Globals/SecuritySettings.h +++ b/src/src/Globals/SecuritySettings.h @@ -2,8 +2,10 @@ #define GLOBALS_SECURITY_SETTINGS_H #include "../DataStructs/SecurityStruct.h" +#include "../DataStructs/ExtendedControllerCredentialsStruct.h" extern SecurityStruct SecuritySettings; +extern ExtendedControllerCredentialsStruct ExtendedControllerCredentials; #endif // GLOBALS_SECURITY_SETTINGS_H \ No newline at end of file