From d4e414a6d5c5670dbfcf97976738ef372d7c781e Mon Sep 17 00:00:00 2001 From: Theo Arends Date: Sat, 2 Jun 2018 16:59:09 +0200 Subject: [PATCH] v6.0.0a - Add CRC to Settings 6.0.0a * Add CRC to Settings making future upgrades more fail-safe * Remove version 3, 4 and pre 5.2 settings auto-upgrade. See https://github.com/arendst/Sonoff-Tasmota/wiki/Upgrade#migration-path * Change default CFG_HOLDER from 0x20161209 to 4617 (=0x1209) - no impact on default upgrades --- README.md | 2 +- sonoff/_releasenotes.ino | 43 ++- sonoff/settings.h | 37 +- sonoff/settings.ino | 514 ++++++++++----------------- sonoff/sonoff.ino | 2 +- sonoff/user_config.h | 2 +- sonoff/user_config_override_sample.h | 2 +- sonoff/xdrv_02_webserver.ino | 58 ++- 8 files changed, 268 insertions(+), 392 deletions(-) diff --git a/README.md b/README.md index cf603026b..6c1bf4e3d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ If you like **Sonoff-Tasmota**, give it a star, or fork it and contribute! ### Development [![Build Status](https://img.shields.io/travis/arendst/Sonoff-Tasmota.svg)](https://travis-ci.org/arendst/Sonoff-Tasmota) -Current version is **5.14.0b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **6.0.0a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### Quick Install Download one of the released binaries from https://github.com/arendst/Sonoff-Tasmota/releases and flash it to your hardware as documented in the wiki. diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index 14ef604f8..5acca6a36 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,22 +1,27 @@ -/* 5.14.0b -* Added Console Commands to send KNX Commands - usage: KnxTx_Cmnd[slot] command - where [slot] is any of the 5 slots on the KNX Menu and command is 0 or 1 - example: KnxTx_Cmnd1 0 -* Added Console Commands to send KNX Values - usage: KnxTx_Val[slot] value - where [slot] is any of the 5 slots on the KNX Menu and value is a number - example: KnxTx_Val1 35 -* Added Slots on the KNX Web Menu to select Group Addess to send data from console commands -* Added Events to trigger rules when received data from KNX - usage on rules as: event#KnxRx_Val[slot] - where [slot] is any of the 5 slots on the KNX Menu - example: rule on event#KnxRx_Val1 do VAR1 %value% endon -* Added Events to trigger rules when received read requests from KNX - usage on rules as: event#KnxRx_Req[slot] - where [slot] is any of the 5 slots on the KNX Menu - example: rule on event#KnxRx_Req1 do KnxTx_Val1 35 endon - * Added Slots on the KNX Web Menu to select Group Addess to receive data to trigger rules +/* 6.0.0a + * Add CRC to Settings making future upgrades more fail-safe + * Remove version 3, 4 and pre 5.2 settings auto-upgrade. See https://github.com/arendst/Sonoff-Tasmota/wiki/Upgrade#migration-path + * Change default CFG_HOLDER from 0x20161209 to 4617 (=0x1209) - no impact on default upgrades + * + * 5.14.0b + * Add Console Commands to send KNX Commands + usage: KnxTx_Cmnd[slot] command + where [slot] is any of the 5 slots on the KNX Menu and command is 0 or 1 + example: KnxTx_Cmnd1 0 + * Add Console Commands to send KNX Values + usage: KnxTx_Val[slot] value + where [slot] is any of the 5 slots on the KNX Menu and value is a number + example: KnxTx_Val1 35 + * Add Slots on the KNX Web Menu to select Group Addess to send data from console commands + * Add Events to trigger rules when received data from KNX + usage on rules as: event#KnxRx_Val[slot] + where [slot] is any of the 5 slots on the KNX Menu + example: rule on event#KnxRx_Val1 do VAR1 %value% endon + * Add Events to trigger rules when received read requests from KNX + usage on rules as: event#KnxRx_Req[slot] + where [slot] is any of the 5 slots on the KNX Menu + example: rule on event#KnxRx_Req1 do KnxTx_Val1 35 endon + * Add Slots on the KNX Web Menu to select Group Addess to receive data to trigger rules * Add two rule sets of 511 characters using commands rule1, rule2 and rule3 * Add Ukranian language file * Add rule support for IrReceive and RfReceive (#2758) diff --git a/sonoff/settings.h b/sonoff/settings.h index 0c4a8617c..bf947d350 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -114,12 +114,21 @@ typedef union { }; } Timer; +/* struct SYSCFG { - unsigned long cfg_holder; // 000 + unsigned long cfg_holder; // 000 Pre v6 header unsigned long save_flag; // 004 unsigned long version; // 008 unsigned long bootcount; // 00C - SysBitfield flag; // 010 Add flag since 5.0.2 +*/ +struct SYSCFG { + uint16_t cfg_holder; // 000 v6 header + uint16_t cfg_size; // 002 + unsigned long save_flag; // 004 + unsigned long version; // 008 + uint16_t bootcount; // 00C + uint16_t cfg_crc; // 00E + SysBitfield flag; // 010 int16_t save_data; // 014 int8_t timezone; // 016 char ota_url[101]; // 017 @@ -163,11 +172,13 @@ struct SYSCFG { uint16_t pwm_frequency; // 2E6 power_t power; // 2E8 uint16_t pwm_value[MAX_PWMS]; // 2EC - int16_t altitude; // 2F6 Add since 5.8.0i + int16_t altitude; // 2F6 uint16_t tele_period; // 2F8 - uint8_t ex_power; // 2FA Not used since 5.8.0j + + byte free_2fa[1]; // 2FA + uint8_t ledstate; // 2FB - uint8_t param[PARAM8_SIZE]; // 2FC was domoticz_in_topic until 5.1.6 + uint8_t param[PARAM8_SIZE]; // 2FC int16_t toffset[2]; // 30E byte free_312[1]; // 312 @@ -204,19 +215,9 @@ struct SYSCFG { uint16_t blinktime; // 39A uint16_t blinkcount; // 39C uint16_t light_rotation; // 39E - uint8_t ws_red; // 3A0 Not used since 5.8.0 - uint8_t ws_green; // 3A1 Not used since 5.8.0 - uint8_t ws_blue; // 3A2 Not used since 5.8.0 - uint8_t ws_ledtable; // 3A3 Not used since 5.8.0 - uint8_t ws_dimmer; // 3A4 Not used since 5.8.0 - uint8_t ws_fade; // 3A5 Not used since 5.8.0 - uint8_t ws_speed; // 3A6 Not used since 5.8.0 - uint8_t ws_scheme; // 3A7 Not used since 5.8.0 - uint8_t ex_ws_width; // 3A8 Not used since 5.8.0 - byte free_3A9[1]; // 3A9 + byte free_3A0[12]; // 3A9 - uint16_t ws_wakeup; // 3AA Not used since 5.8.0 char friendlyname[MAX_FRIENDLYNAMES][33]; // 3AC char switch_topic[33]; // 430 char serial_delimiter; // 451 @@ -250,9 +251,9 @@ struct SYSCFG { byte free_542[2]; // 542 uint32_t ip_address[4]; // 544 - unsigned long energy_kWhtotal; // 554 + unsigned long energy_kWhtotal; // 554 char mqtt_fulltopic[100]; // 558 - SysBitfield2 flag2; // 5BC Add flag2 since 5.9.2 + SysBitfield2 flag2; // 5BC unsigned long pulse_counter[MAX_COUNTERS]; // 5C0 uint16_t pulse_counter_type; // 5D0 uint16_t pulse_counter_debounce; // 5D2 diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 170087767..2b7803304 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -67,25 +67,25 @@ #define RTC_MEM_VALID 0xA55A -uint32_t rtc_settings_hash = 0; +uint32_t rtc_settings_crc = 0; -uint32_t GetRtcSettingsHash() +uint32_t GetRtcSettingsCrc() { - uint32_t hash = 0; + uint32_t crc = 0; uint8_t *bytes = (uint8_t*)&RtcSettings; for (uint16_t i = 0; i < sizeof(RTCMEM); i++) { - hash += bytes[i]*(i+1); + crc += bytes[i]*(i+1); } - return hash; + return crc; } void RtcSettingsSave() { - if (GetRtcSettingsHash() != rtc_settings_hash) { + if (GetRtcSettingsCrc() != rtc_settings_crc) { RtcSettings.valid = RTC_MEM_VALID; ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM)); - rtc_settings_hash = GetRtcSettingsHash(); + rtc_settings_crc = GetRtcSettingsCrc(); #ifdef DEBUG_THEO AddLog_P(LOG_LEVEL_DEBUG, PSTR("Dump: Save")); RtcSettingsDump(); @@ -111,7 +111,7 @@ void RtcSettingsLoad() RtcSettings.power = Settings.power; RtcSettingsSave(); } - rtc_settings_hash = GetRtcSettingsHash(); + rtc_settings_crc = GetRtcSettingsCrc(); } boolean RtcSettingsValid() @@ -133,15 +133,12 @@ extern "C" uint32_t _SPIFFS_end; // From libraries/EEPROM/EEPROM.cpp EEPROMClass #define SPIFFS_END ((uint32_t)&_SPIFFS_end - 0x40200000) / SPI_FLASH_SEC_SIZE -// Version 3.x config -#define SETTINGS_LOCATION_3 SPIFFS_END - 4 - // Version 4.2 config = eeprom area #define SETTINGS_LOCATION SPIFFS_END // No need for SPIFFS as it uses EEPROM area // Version 5.2 allow for more flash space #define CFG_ROTATES 8 // Number of flash sectors used (handles uploads) -uint32_t settings_hash = 0; +uint16_t settings_crc = 0; uint32_t settings_location = SETTINGS_LOCATION; uint8_t *settings_buffer = NULL; @@ -186,15 +183,15 @@ bool SettingsBufferAlloc() return true; } -uint32_t GetSettingsHash() +uint16_t GetSettingsCrc() { - uint32_t hash = 0; + uint16_t crc = 0; uint8_t *bytes = (uint8_t*)&Settings; for (uint16_t i = 0; i < sizeof(SYSCFG); i++) { - hash += bytes[i]*(i+1); + if ((i < 14) || (i > 15)) { crc += bytes[i]*(i+1); } // Skip crc } - return hash; + return crc; } void SettingsSaveAll() @@ -228,7 +225,7 @@ void SettingsSave(byte rotate) * stop_flash_rotate 1 = Allow only eeprom flash slot use (SetOption12 1) */ #ifndef BE_MINIMAL - if ((GetSettingsHash() != settings_hash) || rotate) { + if ((GetSettingsCrc() != settings_crc) || rotate) { if (1 == rotate) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade) stop_flash_rotate = 1; } @@ -244,6 +241,8 @@ void SettingsSave(byte rotate) } } Settings.save_flag++; + Settings.cfg_size = sizeof(SYSCFG); + Settings.cfg_crc = GetSettingsCrc(); ESP.flashEraseSector(settings_location); ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); if (!stop_flash_rotate && rotate) { @@ -255,7 +254,8 @@ void SettingsSave(byte rotate) snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"), settings_location, Settings.save_flag, sizeof(SYSCFG)); AddLog(LOG_LEVEL_DEBUG); - settings_hash = GetSettingsHash(); + + settings_crc = Settings.cfg_crc; } #endif // BE_MINIMAL RtcSettingsSave(); @@ -266,36 +266,28 @@ void SettingsLoad() /* Load configuration from eeprom or one of 7 slots below if first load does not stop_flash_rotate */ struct SYSCFGH { - unsigned long cfg_holder; - unsigned long save_flag; + uint16_t cfg_holder; // 000 + uint16_t cfg_size; // 002 + unsigned long save_flag; // 004 } _SettingsH; + bool bad_crc = false; settings_location = SETTINGS_LOCATION +1; for (byte 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)); - -// snprintf_P(log_data, sizeof(log_data), PSTR("Cnfg: Check at %X with count %d and holder %X"), settings_location -1, _SettingsH.save_flag, _SettingsH.cfg_holder); -// AddLog(LOG_LEVEL_DEBUG); - - if (((Settings.version > 0x05000200) && Settings.flag.stop_flash_rotate) || (Settings.cfg_holder != _SettingsH.cfg_holder) || (Settings.save_flag > _SettingsH.save_flag)) { + 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; } 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); + 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.cfg_holder != CFG_HOLDER) { - // Auto upgrade - ESP.flashRead((SETTINGS_LOCATION_3) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - ESP.flashRead((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&_SettingsH, sizeof(SYSCFGH)); - if (Settings.save_flag < _SettingsH.save_flag) ESP.flashRead((SETTINGS_LOCATION_3 + 1) * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(SYSCFG)); - if ((Settings.cfg_holder != CFG_HOLDER) || (Settings.version >= 0x04020000)) SettingsDefault(); - } - settings_hash = GetSettingsHash(); + if (bad_crc || (Settings.cfg_holder != (uint16_t)CFG_HOLDER)) { SettingsDefault(); } + settings_crc = GetSettingsCrc(); RtcSettingsLoad(); } @@ -372,50 +364,110 @@ void SettingsDefaultSet1() { memset(&Settings, 0x00, sizeof(SYSCFG)); - Settings.cfg_holder = CFG_HOLDER; + Settings.cfg_holder = (uint16_t)CFG_HOLDER; + Settings.cfg_size = sizeof(SYSCFG); // Settings.save_flag = 0; Settings.version = VERSION; // Settings.bootcount = 0; +// Settings.cfg_crc = 0; } void SettingsDefaultSet2() { memset((char*)&Settings +16, 0x00, sizeof(SYSCFG) -16); - Settings.flag.save_state = SAVE_STATE; - //Settings.flag.button_restrict = 0; - //Settings.flag.value_units = 0; - Settings.flag.mqtt_enabled = MQTT_USE; - //Settings.flag.mqtt_response = 0; - Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN; - Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; - Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; - Settings.flag.pwm_control = 1; - Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE; - - Settings.flag2.emulation = EMULATION; - +// Settings.flag.value_units = 0; +// Settings.flag.stop_flash_rotate = 0; Settings.save_data = SAVE_DATA; - Settings.timezone = APP_TIMEZONE; + Settings.sleep = APP_SLEEP; + + // Module +// Settings.flag.interlock = 0; + Settings.module = MODULE; +// for (byte i = 0; i < MAX_GPIO_PIN; i++) { Settings.my_gp.io[i] = 0; } + strlcpy(Settings.friendlyname[0], FRIENDLY_NAME, sizeof(Settings.friendlyname[0])); + strlcpy(Settings.friendlyname[1], FRIENDLY_NAME"2", sizeof(Settings.friendlyname[1])); + strlcpy(Settings.friendlyname[2], FRIENDLY_NAME"3", sizeof(Settings.friendlyname[2])); + strlcpy(Settings.friendlyname[3], FRIENDLY_NAME"4", sizeof(Settings.friendlyname[3])); strlcpy(Settings.ota_url, OTA_URL, sizeof(Settings.ota_url)); + + // Power + Settings.flag.save_state = SAVE_STATE; + Settings.power = APP_POWER; + Settings.poweronstate = APP_POWERON_STATE; + Settings.blinktime = APP_BLINKTIME; + Settings.blinkcount = APP_BLINKCOUNT; + Settings.ledstate = APP_LEDSTATE; + Settings.pulse_timer[0] = APP_PULSETIME; +// for (byte i = 1; i < MAX_PULSETIMERS; i++) { Settings.pulse_timer[i] = 0; } + + // Serial Settings.baudrate = APP_BAUDRATE / 1200; Settings.sbaudrate = SOFT_BAUDRATE / 1200; Settings.serial_delimiter = 0xff; - Settings.seriallog_level = SERIAL_LOG_LEVEL; + + // Wifi + ParseIp(&Settings.ip_address[0], WIFI_IP_ADDRESS); + ParseIp(&Settings.ip_address[1], WIFI_GATEWAY); + ParseIp(&Settings.ip_address[2], WIFI_SUBNETMASK); + ParseIp(&Settings.ip_address[3], WIFI_DNS); + Settings.sta_config = WIFI_CONFIG_TOOL; // Settings.sta_active = 0; strlcpy(Settings.sta_ssid[0], STA_SSID1, sizeof(Settings.sta_ssid[0])); strlcpy(Settings.sta_pwd[0], STA_PASS1, sizeof(Settings.sta_pwd[0])); strlcpy(Settings.sta_ssid[1], STA_SSID2, sizeof(Settings.sta_ssid[1])); strlcpy(Settings.sta_pwd[1], STA_PASS2, sizeof(Settings.sta_pwd[1])); strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname)); - Settings.sta_config = WIFI_CONFIG_TOOL; + + // Syslog strlcpy(Settings.syslog_host, SYS_LOG_HOST, sizeof(Settings.syslog_host)); Settings.syslog_port = SYS_LOG_PORT; Settings.syslog_level = SYS_LOG_LEVEL; + + // Webserver + Settings.flag2.emulation = EMULATION; Settings.webserver = WEB_SERVER; Settings.weblog_level = WEB_LOG_LEVEL; + strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password)); + // Button +// Settings.flag.button_restrict = 0; +// Settings.flag.button_swap = 0; +// Settings.flag.button_single = 0; + Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time + + // Switch + for (byte i = 0; i < MAX_SWITCHES; i++) { Settings.switchmode[i] = SWITCH_MODE; } + + // MQTT + Settings.flag.mqtt_enabled = MQTT_USE; +// Settings.flag.mqtt_response = 0; + Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN; + Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; + Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; +// Settings.flag.mqtt_sensor_retain = 0; +// Settings.flag.mqtt_offline = 0; +// Settings.flag.mqtt_serial = 0; +// Settings.flag.device_index_enable = 0; + strlcpy(Settings.mqtt_host, MQTT_HOST, sizeof(Settings.mqtt_host)); + Settings.mqtt_port = MQTT_PORT; + strlcpy(Settings.mqtt_client, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client)); + strlcpy(Settings.mqtt_user, MQTT_USER, sizeof(Settings.mqtt_user)); + strlcpy(Settings.mqtt_pwd, MQTT_PASS, sizeof(Settings.mqtt_pwd)); + strlcpy(Settings.mqtt_topic, MQTT_TOPIC, sizeof(Settings.mqtt_topic)); + strlcpy(Settings.button_topic, "0", sizeof(Settings.button_topic)); + strlcpy(Settings.switch_topic, "0", sizeof(Settings.switch_topic)); + strlcpy(Settings.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(Settings.mqtt_grptopic)); + strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic)); + Settings.mqtt_retry = MQTT_RETRY_SECS; + strlcpy(Settings.mqtt_prefix[0], SUB_PREFIX, sizeof(Settings.mqtt_prefix[0])); + strlcpy(Settings.mqtt_prefix[1], PUB_PREFIX, sizeof(Settings.mqtt_prefix[1])); + strlcpy(Settings.mqtt_prefix[2], PUB_PREFIX2, sizeof(Settings.mqtt_prefix[2])); + strlcpy(Settings.state_text[0], MQTT_STATUS_OFF, sizeof(Settings.state_text[0])); + strlcpy(Settings.state_text[1], MQTT_STATUS_ON, sizeof(Settings.state_text[1])); + strlcpy(Settings.state_text[2], MQTT_CMND_TOGGLE, sizeof(Settings.state_text[2])); + strlcpy(Settings.state_text[3], MQTT_CMND_HOLD, sizeof(Settings.state_text[3])); char fingerprint[60]; strlcpy(fingerprint, MQTT_FINGERPRINT1, sizeof(fingerprint)); char *p = fingerprint; @@ -427,32 +479,14 @@ void SettingsDefaultSet2() for (byte i = 0; i < 20; i++) { Settings.mqtt_fingerprint[1][i] = strtol(p, &p, 16); } - - strlcpy(Settings.mqtt_host, MQTT_HOST, sizeof(Settings.mqtt_host)); - Settings.mqtt_port = MQTT_PORT; - strlcpy(Settings.mqtt_client, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client)); - strlcpy(Settings.mqtt_user, MQTT_USER, sizeof(Settings.mqtt_user)); - strlcpy(Settings.mqtt_pwd, MQTT_PASS, sizeof(Settings.mqtt_pwd)); - strlcpy(Settings.mqtt_topic, MQTT_TOPIC, sizeof(Settings.mqtt_topic)); - strlcpy(Settings.button_topic, "0", sizeof(Settings.button_topic)); - strlcpy(Settings.mqtt_grptopic, MQTT_GRPTOPIC, sizeof(Settings.mqtt_grptopic)); Settings.tele_period = TELE_PERIOD; - Settings.power = APP_POWER; - Settings.poweronstate = APP_POWERON_STATE; - Settings.ledstate = APP_LEDSTATE; - Settings.blinktime = APP_BLINKTIME; - Settings.blinkcount = APP_BLINKCOUNT; - Settings.sleep = APP_SLEEP; - - Settings.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER; - for (byte i = 0; i < MAX_SWITCHES; i++) { - Settings.switchmode[i] = SWITCH_MODE; -// Settings.domoticz_relay_idx[i] = 0; -// Settings.domoticz_key_idx[i] = 0; -// Settings.domoticz_switch_idx[i] = 0; - } - + // Energy + Settings.flag2.current_resolution = 3; +// Settings.flag2.voltage_resolution = 0; +// Settings.flag2.wattage_resolution = 0; + Settings.flag2.energy_resolution = ENERGY_RESOLUTION; + Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY; Settings.energy_power_delta = DEFAULT_POWER_DELTA; Settings.energy_power_calibration = HLW_PREF_PULSE; Settings.energy_voltage_calibration = HLW_UREF_PULSE; @@ -474,122 +508,71 @@ void SettingsDefaultSet2() Settings.energy_max_power_safe_limit_window = SAFE_POWER_WINDOW; // Settings.energy_max_energy = 0; // MaxEnergy // Settings.energy_max_energy_start = 0; // MaxEnergyStart - - SettingsDefaultSet_3_2_4(); - - strlcpy(Settings.friendlyname[0], FRIENDLY_NAME, sizeof(Settings.friendlyname[0])); - strlcpy(Settings.friendlyname[1], FRIENDLY_NAME"2", sizeof(Settings.friendlyname[1])); - strlcpy(Settings.friendlyname[2], FRIENDLY_NAME"3", sizeof(Settings.friendlyname[2])); - strlcpy(Settings.friendlyname[3], FRIENDLY_NAME"4", sizeof(Settings.friendlyname[3])); - - SettingsDefaultSet_3_9_3(); - - strlcpy(Settings.switch_topic, "0", sizeof(Settings.switch_topic)); - - strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password)); - - SettingsDefaultSet_4_0_4(); - Settings.pulse_timer[0] = APP_PULSETIME; - - // 4.0.7 -// for (byte i = 0; i < MAX_PWMS; i++) Settings.pwm_value[i] = 0; - - // 4.0.9 - SettingsDefaultSet_4_0_9(); - - // 4.1.1 + 5.1.6 - SettingsDefaultSet_4_1_1(); - - // 5.0.2 - SettingsDefaultSet_5_0_2(); - - // 5.0.4 // Settings.energy_kWhtotal = 0; RtcSettings.energy_kWhtotal = 0; - // 5.0.5 - strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic)); - - // 5.0.6 - Settings.mqtt_retry = MQTT_RETRY_SECS; - - // 5.1.7 - Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time - - // 5.2.0 - Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY; - - // 5.4.1 + // RF Bridge +// for (byte i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; } memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); - // 5.8.0 - Settings.light_pixels = WS2812_LEDS; -// Settings.light_rotation = 0; + // Domoticz + Settings.domoticz_update_timer = DOMOTICZ_UPDATE_TIMER; +// for (byte i = 0; i < MAX_DOMOTICZ_IDX; i++) { +// Settings.domoticz_relay_idx[i] = 0; +// Settings.domoticz_key_idx[i] = 0; +// Settings.domoticz_switch_idx[i] = 0; +// } +// for (byte i = 0; i < MAX_DOMOTICZ_SNS_IDX; i++) { +// Settings.domoticz_sensor_idx[i] = 0; +// } - // 5.8.1 + // Sensor + Settings.flag.temperature_conversion = TEMP_CONVERSION; + Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION; + Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION; + Settings.flag2.temperature_resolution = TEMP_RESOLUTION; // Settings.altitude = 0; + + // Rules +// Settings.flag.rules_enabled = 0; +// Settings.flag.rules_once = 0; +// for (byte i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; } + + // Home Assistant + Settings.flag.hass_discovery = HOME_ASSISTANT_DISCOVERY_ENABLE; + + // Knx +// Settings.flag.knx_enabled = 0; +// Settings.flag.knx_enable_enhancement = 0; + + // Light + Settings.flag.pwm_control = 1; + //Settings.flag.ws_clock_reverse = 0; + //Settings.flag.light_signal = 0; + //Settings.flag.not_power_linked = 0; + //Settings.flag.decimal_text = 0; Settings.pwm_frequency = PWM_FREQ; Settings.pwm_range = PWM_RANGE; - SettingsDefaultSet_5_8_1(); - - // 5.9.2 - Settings.flag2.current_resolution = 3; - - // 5.10.1 - SettingsDefaultSet_5_10_1(); - - Settings.latitude = (int)((double)LATITUDE * 1000000); - Settings.longitude = (int)((double)LONGITUDE * 1000000); - - SettingsDefaultSet_5_13_1c(); -} - -/********************************************************************************************/ - -void SettingsDefaultSet_3_2_4() -{ - Settings.ws_red = 255; - Settings.ws_green = 0; - Settings.ws_blue = 0; - Settings.ws_ledtable = 0; - Settings.ws_dimmer = 8; - Settings.ws_fade = 0; - Settings.ws_speed = 1; - Settings.ws_scheme = 0; - Settings.ex_ws_width = 1; - Settings.ws_wakeup = 0; -} - -void SettingsDefaultSet_3_9_3() -{ - for (byte i = 0; i < MAX_DOMOTICZ_IDX; i++) { - Settings.domoticz_switch_idx[i] = 0; - } - for (byte i = 0; i < 12; i++) { - Settings.domoticz_sensor_idx[i] = 0; - } - - Settings.module = MODULE; - for (byte i = 0; i < MAX_GPIO_PIN; i++){ - Settings.my_gp.io[i] = 0; - } - - Settings.light_pixels = WS2812_LEDS; - Settings.light_rotation = 0; for (byte i = 0; i < MAX_PWMS; i++) { Settings.light_color[i] = 255; +// Settings.pwm_value[i] = 0; } - Settings.light_correction = 0; +// Settings.light_correction = 0; Settings.light_dimmer = 10; - Settings.light_fade = 0; +// Settings.light_fade = 0; Settings.light_speed = 1; - Settings.light_scheme = 0; +// Settings.light_scheme = 0; Settings.light_width = 1; - Settings.light_wakeup = 0; -} +// Settings.light_wakeup = 0; + Settings.light_pixels = WS2812_LEDS; +// Settings.light_rotation = 0; + SettingsDefaultSet_5_8_1(); // Clock color -void SettingsDefaultSet_4_0_4() -{ + // Display + SettingsDefaultSet_5_10_1(); // Display settings + + // Time + Settings.timezone = APP_TIMEZONE; strlcpy(Settings.ntp_server[0], NTP_SERVER1, sizeof(Settings.ntp_server[0])); strlcpy(Settings.ntp_server[1], NTP_SERVER2, sizeof(Settings.ntp_server[1])); strlcpy(Settings.ntp_server[2], NTP_SERVER3, sizeof(Settings.ntp_server[2])); @@ -600,39 +583,12 @@ void SettingsDefaultSet_4_0_4() } } } - Settings.pulse_timer[0] = APP_PULSETIME; - for (byte i = 1; i < MAX_PULSETIMERS; i++) { - Settings.pulse_timer[i] = 0; - } + Settings.latitude = (int)((double)LATITUDE * 1000000); + Settings.longitude = (int)((double)LONGITUDE * 1000000); + SettingsDefaultSet_5_13_1c(); // Time STD/DST settings } -void SettingsDefaultSet_4_0_9() -{ - strlcpy(Settings.mqtt_prefix[0], SUB_PREFIX, sizeof(Settings.mqtt_prefix[0])); - strlcpy(Settings.mqtt_prefix[1], PUB_PREFIX, sizeof(Settings.mqtt_prefix[1])); - strlcpy(Settings.mqtt_prefix[2], PUB_PREFIX2, sizeof(Settings.mqtt_prefix[2])); - ParseIp(&Settings.ip_address[0], WIFI_IP_ADDRESS); - ParseIp(&Settings.ip_address[1], WIFI_GATEWAY); - ParseIp(&Settings.ip_address[2], WIFI_SUBNETMASK); - ParseIp(&Settings.ip_address[3], WIFI_DNS); -} - -void SettingsDefaultSet_4_1_1() -{ - strlcpy(Settings.state_text[0], MQTT_STATUS_OFF, sizeof(Settings.state_text[0])); - strlcpy(Settings.state_text[1], MQTT_STATUS_ON, sizeof(Settings.state_text[1])); - strlcpy(Settings.state_text[2], MQTT_CMND_TOGGLE, sizeof(Settings.state_text[2])); - strlcpy(Settings.state_text[3], MQTT_CMND_HOLD, sizeof(Settings.state_text[3])); // v5.1.6 -} - -void SettingsDefaultSet_5_0_2() -{ - Settings.flag.temperature_conversion = TEMP_CONVERSION; - Settings.flag2.temperature_resolution = TEMP_RESOLUTION; - Settings.flag2.humidity_resolution = HUMIDITY_RESOLUTION; - Settings.flag2.pressure_resolution = PRESSURE_RESOLUTION; - Settings.flag2.energy_resolution = ENERGY_RESOLUTION; -} +/********************************************************************************************/ void SettingsDefaultSet_5_8_1() { @@ -704,132 +660,27 @@ void SettingsDefaultSet_5_13_1c() void SettingsDelta() { if (Settings.version != VERSION) { // Fix version dependent changes - if (Settings.version < 0x03010200) { // 3.1.2 - Add parameter - Settings.poweronstate = APP_POWERON_STATE; - } - if (Settings.version < 0x03010600) { // 3.1.6 - Add parameter - Settings.blinktime = APP_BLINKTIME; - Settings.blinkcount = APP_BLINKCOUNT; - } - if (Settings.version < 0x03020400) { // 3.2.4 - Add parameter - SettingsDefaultSet_3_2_4(); - } - if (Settings.version < 0x03020500) { // 3.2.5 - Add parameter - Format(Settings.friendlyname[0], Settings.mqtt_client, sizeof(Settings.friendlyname[0])); - strlcpy(Settings.friendlyname[1], FRIENDLY_NAME"2", sizeof(Settings.friendlyname[1])); - strlcpy(Settings.friendlyname[2], FRIENDLY_NAME"3", sizeof(Settings.friendlyname[2])); - strlcpy(Settings.friendlyname[3], FRIENDLY_NAME"4", sizeof(Settings.friendlyname[3])); - } - if (Settings.version < 0x03020800) { // 3.2.8 - Add parameter - strlcpy(Settings.switch_topic, Settings.button_topic, sizeof(Settings.switch_topic)); - } - if (Settings.version < 0x03020C00) { // 3.2.12 - Add parameter - Settings.sleep = APP_SLEEP; - } - if (Settings.version < 0x03090300) { // 3.9.2d - Add parameter - SettingsDefaultSet_3_9_3(); - } - if (Settings.version < 0x03091400) { - strlcpy(Settings.web_password, WEB_PASSWORD, sizeof(Settings.web_password)); - } - if (Settings.version < 0x03091500) { - for (byte i = 0; i < MAX_SWITCHES; i++) { - Settings.switchmode[i] = SWITCH_MODE; - } - } - if (Settings.version < 0x04000400) { - SettingsDefaultSet_4_0_4(); - } - if (Settings.version < 0x04000500) { - memmove(Settings.my_gp.io, Settings.my_gp.io +1, MAX_GPIO_PIN -1); // move myio 1 byte to front - Settings.my_gp.io[MAX_GPIO_PIN -1] = 0; // Clear ADC0 - } - if (Settings.version < 0x04000700) { - for (byte i = 0; i < MAX_PWMS; i++) { - Settings.pwm_value[i] = 0; - } - } - if (Settings.version < 0x04000804) { - SettingsDefaultSet_4_0_9(); - } - if (Settings.version < 0x04010100) { - SettingsDefaultSet_4_1_1(); - } - if (Settings.version < 0x05000105) { - Settings.flag = { 0 }; - Settings.flag.save_state = SAVE_STATE; -// Settings.flag.button_restrict = 0; -// Settings.flag.value_units = 0; - Settings.flag.mqtt_enabled = MQTT_USE; -// Settings.flag.mqtt_response = 0; -// Settings.flag.mqtt_power_retain = 0; -// Settings.flag.mqtt_button_retain = 0; - Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; - Settings.flag2.emulation = EMULATION; - SettingsDefaultSet_5_0_2(); - - Settings.save_data = SAVE_DATA; - } - if (Settings.version < 0x05000400) { - Settings.energy_kWhtotal = 0; - RtcSettings.energy_kWhtotal = 0; - } - if (Settings.version < 0x05000500) { - strlcpy(Settings.mqtt_fulltopic, MQTT_FULLTOPIC, sizeof(Settings.mqtt_fulltopic)); - } - if (Settings.version < 0x05000600) { - Settings.mqtt_retry = MQTT_RETRY_SECS; - } - if (Settings.version < 0x05010100) { - Settings.pulse_counter_type = 0; - Settings.pulse_counter_debounce = 0; - for (byte i = 0; i < MAX_COUNTERS; i++) { - Settings.pulse_counter[i] = 0; - RtcSettings.pulse_counter[i] = 0; - } - } - if (Settings.version < 0x05010600) { - SettingsDefaultSet_4_1_1(); - } - if (Settings.version < 0x05010700) { - Settings.param[P_HOLD_TIME] = KEY_HOLD_TIME; // Default 4 seconds hold time - } - if (Settings.version < 0x05020000) { - Settings.param[P_MAX_POWER_RETRY] = MAX_POWER_RETRY; - } if (Settings.version < 0x05050000) { - for (byte i = 0; i < 17; i++) { - Settings.rf_code[i][0] = 0; - } + for (byte i = 0; i < 17; i++) { Settings.rf_code[i][0] = 0; } memcpy_P(Settings.rf_code[0], kDefaultRfCode, 9); } if (Settings.version < 0x05080000) { - uint8_t cfg_wsflg = 0; - for (byte i = 0; i < MAX_GPIO_PIN; i++) { - if (GPIO_WS2812 == Settings.my_gp.io[i]) { - cfg_wsflg = 1; - } - } - if (!Settings.light_pixels && cfg_wsflg) { - Settings.light_pixels = WS2812_LEDS; - Settings.light_color[0] = Settings.ws_red; - Settings.light_color[1] = Settings.ws_green; - Settings.light_color[2] = Settings.ws_blue; - Settings.light_dimmer = Settings.ws_dimmer; - Settings.light_correction = Settings.ws_ledtable; - Settings.light_fade = Settings.ws_fade; - Settings.light_speed = Settings.ws_speed; - Settings.light_scheme = Settings.ws_scheme; - Settings.light_width = Settings.ex_ws_width; - Settings.light_wakeup = Settings.ws_wakeup; - } else { - Settings.light_pixels = WS2812_LEDS; - Settings.light_width = 1; - } + Settings.light_pixels = WS2812_LEDS; + Settings.light_width = 1; + Settings.light_color[0] = 255; + Settings.light_color[1] = 0; + Settings.light_color[2] = 0; + Settings.light_dimmer = 10; + Settings.light_correction = 0; + Settings.light_fade = 0; + Settings.light_speed = 1; + Settings.light_scheme = 0; + Settings.light_width = 1; + Settings.light_wakeup = 0; } if (Settings.version < 0x0508000A) { - Settings.power = Settings.ex_power; + Settings.power = 0; Settings.altitude = 0; } if (Settings.version < 0x0508000B) { @@ -881,9 +732,6 @@ void SettingsDelta() Settings.sbaudrate = SOFT_BAUDRATE / 1200; Settings.serial_delimiter = 0xff; } -// if (Settings.version < 0x050C0009) { -// memset(&Settings.timer, 0x00, sizeof(Timer) * MAX_TIMERS); -// } if (Settings.version < 0x050C000A) { Settings.latitude = (int)((double)LATITUDE * 1000000); Settings.longitude = (int)((double)LONGITUDE * 1000000); @@ -907,12 +755,14 @@ void SettingsDelta() SettingsDefaultSet_5_13_1c(); } if (Settings.version < 0x050E0002) { - for (byte i = 1; i < MAX_RULE_SETS; i++) { - Settings.rules[i][0] = '\0'; - } + for (byte i = 1; i < MAX_RULE_SETS; i++) { Settings.rules[i][0] = '\0'; } Settings.rule_enabled = Settings.flag.rules_enabled; Settings.rule_once = Settings.flag.rules_once; } + if (Settings.version < 0x06000000) { + Settings.cfg_size = sizeof(SYSCFG); + Settings.cfg_crc = GetSettingsCrc(); + } Settings.version = VERSION; SettingsSave(1); diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 8a16742aa..b030d63b3 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,7 +25,7 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x050E0002 // 5.14.0b +#define VERSION 0x06000001 // 6.0.0a // Location specific includes #include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_3_0) diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 8cc07d356..1ac534d0f 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -44,7 +44,7 @@ \*********************************************************************************************/ // -- Master parameter control -------------------- -#define CFG_HOLDER 0x20161209 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash +#define CFG_HOLDER 4617 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash // -- Project ------------------------------------- #define PROJECT "sonoff" // PROJECT is used as the default topic delimiter diff --git a/sonoff/user_config_override_sample.h b/sonoff/user_config_override_sample.h index acd66cebe..8b3203904 100644 --- a/sonoff/user_config_override_sample.h +++ b/sonoff/user_config_override_sample.h @@ -47,7 +47,7 @@ Examples : // -- Master parameter control -------------------- #undef CFG_HOLDER -#define CFG_HOLDER 0x20161209 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash +#define CFG_HOLDER 4617 // [Reset 1] Change this value to load SECTION1 configuration parameters to flash // -- Setup your own Wifi settings --------------- #undef STA_SSID1 diff --git a/sonoff/xdrv_02_webserver.ino b/sonoff/xdrv_02_webserver.ino index 7059bcc4c..0ecea9f79 100644 --- a/sonoff/xdrv_02_webserver.ino +++ b/sonoff/xdrv_02_webserver.ino @@ -942,6 +942,7 @@ void HandleBackupConfiguration() WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), ""); memcpy(settings_buffer, &Settings, sizeof(Settings)); +/* settings_buffer[0] = CONFIG_FILE_SIGN; settings_buffer[1] = (!config_xor_on_set) ? 0 : 1; if (settings_buffer[1]) { @@ -949,6 +950,12 @@ void HandleBackupConfiguration() settings_buffer[i] ^= (config_xor_on_set +i); } } +*/ + if (config_xor_on_set) { + for (uint16_t i = 2; i < sizeof(Settings); i++) { + settings_buffer[i] ^= (config_xor_on_set +i); + } + } #ifdef ARDUINO_ESP8266_RELEASE_2_3_0 size_t written = myClient.write((const char*)settings_buffer, sizeof(Settings)); @@ -1276,7 +1283,7 @@ void HandleUploadLoop() if (UPLOAD_FILE_START == upload.status) { restart_flag = 60; if (0 == upload.filename.c_str()[0]) { - upload_error = 1; + upload_error = 1; // No file selected return; } SettingsSave(1); // Free flash for upload @@ -1284,7 +1291,7 @@ void HandleUploadLoop() AddLog(LOG_LEVEL_INFO); if (upload_file_type) { if (!SettingsBufferAlloc()) { - upload_error = 2; + upload_error = 2; // Not enough space return; } } else { @@ -1298,7 +1305,7 @@ void HandleUploadLoop() if (Settings.flag.mqtt_enabled) MqttDisconnect(); uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if (!Update.begin(maxSketchSpace)) { //start with max available size - upload_error = 2; + upload_error = 2; // Not enough space return; } } @@ -1306,20 +1313,15 @@ void HandleUploadLoop() } else if (!upload_error && (UPLOAD_FILE_WRITE == upload.status)) { if (0 == upload.totalSize) { if (upload_file_type) { - if (upload.buf[0] != CONFIG_FILE_SIGN) { - upload_error = 8; - return; - } - config_xor_on = upload.buf[1]; config_block_count = 0; } else { if (upload.buf[0] != 0xE9) { - upload_error = 3; + upload_error = 3; // Magic byte is not 0xE9 return; } uint32_t bin_flash_size = ESP.magicFlashChipSize((upload.buf[3] & 0xf0) >> 4); if(bin_flash_size > ESP.getFlashChipRealSize()) { - upload_error = 4; + upload_error = 4; // Program flash size is larger than real flash size return; } upload.buf[2] = 3; // Force DOUT - ESP8285 @@ -1328,7 +1330,7 @@ void HandleUploadLoop() if (upload_file_type) { // config if (!upload_error) { if (upload.currentSize > (sizeof(Settings) - (config_block_count * HTTP_UPLOAD_BUFLEN))) { - upload_error = 9; + upload_error = 9; // File too large return; } memcpy(settings_buffer + (config_block_count * HTTP_UPLOAD_BUFLEN), upload.buf, upload.currentSize); @@ -1336,7 +1338,7 @@ void HandleUploadLoop() } } else { // firmware if (!upload_error && (Update.write(upload.buf, upload.currentSize) != upload.currentSize)) { - upload_error = 5; + upload_error = 5; // Upload buffer miscompare return; } if (_serialoutput) { @@ -1350,19 +1352,37 @@ void HandleUploadLoop() Serial.println(); } if (upload_file_type) { - if (config_xor_on) { + if (config_xor_on_set) { for (uint16_t i = 2; i < sizeof(Settings); i++) { settings_buffer[i] ^= (config_xor_on_set +i); } } - SettingsDefaultSet2(); - memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16); - memcpy((char*)&Settings +8, settings_buffer +8, 4); // Restore version and auto upgrade - SettingsBufferFree(); + bool valid_settings = false; + unsigned long buffer_version = settings_buffer[11] << 24 | settings_buffer[10] << 16 | settings_buffer[9] << 8 | settings_buffer[8]; + if (buffer_version > 0x06000000) { + uint16_t buffer_size = settings_buffer[3] << 8 | settings_buffer[2]; + uint16_t buffer_crc = settings_buffer[15] << 8 | settings_buffer[14]; + uint16_t crc = 0; + for (uint16_t i = 0; i < buffer_size; i++) { + if ((i < 14) || (i > 15)) { crc += settings_buffer[i]*(i+1); } // Skip crc + } + valid_settings = (buffer_crc == crc); + } else { + valid_settings = (settings_buffer[0] == CONFIG_FILE_SIGN); + } + if (valid_settings) { + SettingsDefaultSet2(); + memcpy((char*)&Settings +16, settings_buffer +16, sizeof(Settings) -16); + Settings.version = buffer_version; // Restore version and auto upgrade after restart + SettingsBufferFree(); + } else { + upload_error = 8; // File invalid + return; + } } else { if (!Update.end(true)) { // true to set the size to the current progress if (_serialoutput) { Update.printError(Serial); } - upload_error = 6; + upload_error = 6; // Upload failed. Enable logging 3 return; } } @@ -1373,7 +1393,7 @@ void HandleUploadLoop() } else if (UPLOAD_FILE_ABORTED == upload.status) { restart_flag = 0; MqttRetryCounter(0); - upload_error = 7; + upload_error = 7; // Upload aborted if (!upload_file_type) { Update.end(); } } delay(0);