diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 78200f2d8..ab986d522 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,8 @@ -/* 6.4.1.12 20190128 +/* 6.4.1.13 20190130 + * Add command SetOption36 to control boot loop default restoration (#4645, #5063) + * Add resiliency to saved Settings (#5065) + * + * 6.4.1.12 20190128 * Change code use of boolean to bool and byte to uint8_t * Change code uint8_t flags to bool flags * diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 83bbb7b65..c9c6505d5 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -54,6 +54,7 @@ #define SAVE_DATA 1 // [SaveData] Save changed parameters to Flash (0 = disable, 1 - 3600 seconds) #define SAVE_STATE 1 // [SetOption0] Save changed power state to Flash (0 = disable, 1 = enable) +#define BOOT_LOOP_OFFSET 1 // [SetOption36] Number of boot loops before starting restoring defaults (0 = disable, 1..200 = boot loops offset) // -- Wifi ---------------------------------------- #define WIFI_IP_ADDRESS "0.0.0.0" // [IpAddress1] Set to 0.0.0.0 for using DHCP or enter a static IP address diff --git a/sonoff/settings.ino b/sonoff/settings.ino index c1b84cafa..13634d541 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -447,31 +447,50 @@ void SettingsSave(uint8_t rotate) void SettingsLoad(void) { -/* Load configuration from eeprom or one of 7 slots below if first load does not stop_flash_rotate - */ + // Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate struct SYSCFGH { uint16_t cfg_holder; // 000 uint16_t cfg_size; // 002 unsigned long save_flag; // 004 } _SettingsH; + unsigned long save_flag = 0; - bool bad_crc = false; - settings_location = SETTINGS_LOCATION +1; + settings_location = 0; + uint32_t flash_location = SETTINGS_LOCATION +1; for (uint8_t i = 0; i < CFG_ROTATES; i++) { - settings_location--; - ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - ESP.flashRead((settings_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); - if (Settings.version > 0x06000000) { bad_crc = (Settings.cfg_crc != GetSettingsCrc()); } - if (Settings.flag.stop_flash_rotate || bad_crc || (Settings.cfg_holder != _SettingsH.cfg_holder) || (Settings.save_flag > _SettingsH.save_flag)) { - break; + flash_location--; + ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + + bool valid = false; + if (Settings.version > 0x06000000) { + valid = (Settings.cfg_crc == GetSettingsCrc()); + } else { + ESP.flashRead((flash_location -1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); + valid = (Settings.cfg_holder == _SettingsH.cfg_holder); } + if (valid) { + if (Settings.save_flag > save_flag) { + save_flag = Settings.save_flag; + settings_location = flash_location; + if (Settings.flag.stop_flash_rotate) { + break; + } + } + } + delay(1); } - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), settings_location, Settings.save_flag); - AddLog(LOG_LEVEL_DEBUG); + if (settings_location > 0) { + ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"), + settings_location, Settings.save_flag); + AddLog(LOG_LEVEL_DEBUG); + } #ifndef BE_MINIMAL - if (bad_crc || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { SettingsDefault(); } + if (!settings_location || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h + SettingsDefault(); + } settings_crc = GetSettingsCrc(); #endif // BE_MINIMAL @@ -567,6 +586,7 @@ void SettingsDefaultSet2(void) // Settings.flag.value_units = 0; // Settings.flag.stop_flash_rotate = 0; Settings.save_data = SAVE_DATA; + Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; Settings.sleep = APP_SLEEP; if (Settings.sleep < 50) { Settings.sleep = 50; // Default to 50 for sleep, for now @@ -1027,6 +1047,9 @@ void SettingsDelta(void) Settings.interlock[0] = 0xFF; // Legacy support using all relays in one interlock group for (uint8_t i = 1; i < MAX_INTERLOCKS; i++) { Settings.interlock[i] = 0; } } + if (Settings.version < 0x0604010D) { + Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; + } Settings.version = VERSION; SettingsSave(1); diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 699d8c819..9ba91f091 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -227,7 +227,7 @@ enum ButtonStates { PRESSED, NOT_PRESSED }; enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER }; -enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_MAX_PARAM8}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49 +enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_BOOT_LOOP_OFFSET, P_MAX_PARAM8}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49 enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_MAX_SENSORS}; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index fbf256134..694f7d4c9 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2490,30 +2490,32 @@ void setup(void) Settings.flag2.emulation = 0; #endif // USE_EMULATION - // Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts) - if (RtcReboot.fast_reboot_count > 1) { // Restart twice - Settings.flag3.user_esp8285_enable = 0; // Disable ESP8285 Generic GPIOs interfering with flash SPI - if (RtcReboot.fast_reboot_count > 2) { // Restart 3 times - for (uint8_t i = 0; i < MAX_RULE_SETS; i++) { - if (bitRead(Settings.rule_stop, i)) { - bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop + if (Settings.param[P_BOOT_LOOP_OFFSET]) { + // Disable functionality as possible cause of fast restart within BOOT_LOOP_TIME seconds (Exception, WDT or restarts) + if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET]) { // Restart twice + Settings.flag3.user_esp8285_enable = 0; // Disable ESP8285 Generic GPIOs interfering with flash SPI + if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +1) { // Restart 3 times + for (uint8_t i = 0; i < MAX_RULE_SETS; i++) { + if (bitRead(Settings.rule_stop, i)) { + bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop + } } } - } - if (RtcReboot.fast_reboot_count > 3) { // Restarted 4 times - Settings.rule_enabled = 0; // Disable all rules - } - if (RtcReboot.fast_reboot_count > 4) { // Restarted 5 times - for (uint8_t i = 0; i < sizeof(Settings.my_gp); i++) { - Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors + if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times + Settings.rule_enabled = 0; // Disable all rules } + if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +3) { // Restarted 5 times + for (uint8_t i = 0; i < sizeof(Settings.my_gp); i++) { + Settings.my_gp.io[i] = GPIO_NONE; // Reset user defined GPIO disabling sensors + } + } + if (RtcReboot.fast_reboot_count > Settings.param[P_BOOT_LOOP_OFFSET] +4) { // Restarted 6 times + Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic + // Settings.last_module = SONOFF_BASIC; + } + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count); + AddLog(LOG_LEVEL_DEBUG); } - if (RtcReboot.fast_reboot_count > 5) { // Restarted 6 times - Settings.module = SONOFF_BASIC; // Reset module to Sonoff Basic -// Settings.last_module = SONOFF_BASIC; - } - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcReboot.fast_reboot_count); - AddLog(LOG_LEVEL_DEBUG); } Format(mqtt_client, Settings.mqtt_client, sizeof(mqtt_client)); diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 0ad920b27..23808c4c9 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -296,6 +296,7 @@ enum SupportedModules { KA10, ZX2820, MI_DESK_LAMP, + SP10, SYF05, MAXMODULE }; @@ -582,6 +583,7 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { SK03_TUYA, DIGOO, KA10, + SP10, NEO_COOLCAM, // Socket Relay Devices OBI, OBI2, @@ -1805,6 +1807,25 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_ROT_B, // GPIO13 Rotary switch B pin 0, 0, 0, 0 }, + { "SP10", // Tuya SP10 (ESP8285 - BL0937 Energy Monitoring) + // https://www.aliexpress.com/item/Smart-Mini-WiFi-Plug-Outlet-Switch-Work-With-ForEcho-Alexa-Google-Home-Remote-EU-Smart-Socket/32963670423.html + 0, // GPIO00 + GPIO_PWM1, // GPIO01 Nightlight + 0, // GPIO02 + GPIO_KEY1, // GPIO03 Button + GPIO_HJL_CF, // GPIO04 BL0937 CF power + GPIO_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + 0, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + 0, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPIO_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage) + GPIO_LED1, // GPIO13 Blue LED - Link status + GPIO_REL1, // GPIO14 Relay 1 and red LED + 0, 0, 0 + }, { "SYF05", // Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726 // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 83db36b91..099c8955f 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x0604010C +#define VERSION 0x0604010D #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 80c5b4ebe..6b6d1bff3 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -67,7 +67,7 @@ const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM = "%s,\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT "\"white_value_scale\":100," // (No abbreviation defined) - "\"whit_val_tpl\":\"{{ value_json.Channel[3] }}\""; + "\"whit_val_tpl\":\"{{value_json.Channel[3]}}\""; const char HASS_DISCOVER_LIGHT_CT[] PROGMEM = "%s,\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT diff --git a/sonoff/xsns_40_pn532_i2c.ino b/sonoff/xsns_40_pn532_i2c.ino index 6718ffc4e..640e21c6e 100644 --- a/sonoff/xsns_40_pn532_i2c.ino +++ b/sonoff/xsns_40_pn532_i2c.ino @@ -432,6 +432,7 @@ void PN532_ScanForTag(void) } if (pn532_i2c_function == 2) { #ifdef USE_PN532_DATA_RAW + memcpy(&card_data,&pn532_i2c_newdata,sizeof(card_data)); if (mifareclassic_WriteDataBlock(1, card_data)) { set_success = true; snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Data write successful"); @@ -441,13 +442,14 @@ void PN532_ScanForTag(void) #else bool IsAlphaNumeric = true; for (uint8_t i = 0;i < pn532_i2c_newdata_len;i++) { - if ((!isalpha(pn532_i2c_newdata[i])) || (!isdigit(pn532_i2c_newdata[i]))) { + if ((!isalpha(pn532_i2c_newdata[i])) && (!isdigit(pn532_i2c_newdata[i]))) { IsAlphaNumeric = false; } } if (IsAlphaNumeric) { + memcpy(&card_data,&pn532_i2c_newdata,pn532_i2c_newdata_len); + card_data[pn532_i2c_newdata_len] = '\0'; // Enforce null termination if (mifareclassic_WriteDataBlock(1, card_data)) { - memcpy(&card_data,&pn532_i2c_newdata,sizeof(card_data)); set_success = true; snprintf_P(log_data, sizeof(log_data),"I2C: PN532 NFC - Data write successful"); AddLog(LOG_LEVEL_INFO);