2017-02-19 16:49:17 +00:00
/*
2021-06-13 10:10:52 +01:00
settings . ino - user settings for Tasmota
2017-05-13 12:02:10 +01:00
2021-01-01 12:44:04 +00:00
Copyright ( C ) 2021 Theo Arends
2017-05-13 12:02:10 +01:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2017-02-19 16:49:17 +00:00
*/
2017-02-28 15:01:48 +00:00
/*********************************************************************************************\
* RTC memory
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-03-31 10:59:04 +01:00
const uint16_t RTC_MEM_VALID = 0xA55A ;
2017-02-28 15:01:48 +00:00
2018-06-02 15:59:09 +01:00
uint32_t rtc_settings_crc = 0 ;
2017-02-28 15:01:48 +00:00
2021-01-22 10:54:15 +00:00
uint32_t GetRtcSettingsCrc ( void ) {
2018-06-02 15:59:09 +01:00
uint32_t crc = 0 ;
2017-10-18 17:22:34 +01:00
uint8_t * bytes = ( uint8_t * ) & RtcSettings ;
2017-02-28 15:01:48 +00:00
2020-04-19 12:08:04 +01:00
for ( uint32_t i = 0 ; i < sizeof ( RtcSettings ) ; i + + ) {
2018-06-02 15:59:09 +01:00
crc + = bytes [ i ] * ( i + 1 ) ;
2017-04-25 17:24:42 +01:00
}
2018-06-02 15:59:09 +01:00
return crc ;
2017-02-28 15:01:48 +00:00
}
2021-01-22 10:54:15 +00:00
void RtcSettingsSave ( void ) {
2021-06-11 17:14:12 +01:00
RtcSettings . baudrate = Settings - > baudrate * 300 ;
2022-06-16 15:15:54 +01:00
if ( UtcTime ( ) > START_VALID_TIME ) { // 2016-01-01
RtcSettings . utc_time = UtcTime ( ) ;
}
2018-06-02 15:59:09 +01:00
if ( GetRtcSettingsCrc ( ) ! = rtc_settings_crc ) {
2021-10-21 15:24:41 +01:00
if ( RTC_MEM_VALID ! = RtcSettings . valid ) {
memset ( & RtcSettings , 0 , sizeof ( RtcSettings ) ) ;
RtcSettings . valid = RTC_MEM_VALID ;
2022-08-05 14:25:39 +01:00
// RtcSettings.ex_energy_kWhtoday = Settings->ex_energy_kWhtoday;
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
2021-10-21 15:24:41 +01:00
for ( uint32_t i = 0 ; i < 3 ; i + + ) {
RtcSettings . energy_kWhtoday_ph [ i ] = Settings - > energy_kWhtoday_ph [ i ] ;
RtcSettings . energy_kWhtotal_ph [ i ] = Settings - > energy_kWhtotal_ph [ i ] ;
2022-04-16 15:07:42 +01:00
RtcSettings . energy_kWhexport_ph [ i ] = Settings - > energy_kWhexport_ph [ i ] ;
2021-10-21 15:24:41 +01:00
}
RtcSettings . energy_usage = Settings - > energy_usage ;
for ( uint32_t i = 0 ; i < MAX_COUNTERS ; i + + ) {
RtcSettings . pulse_counter [ i ] = Settings - > pulse_counter [ i ] ;
}
RtcSettings . power = Settings - > power ;
// RtcSettings.baudrate = Settings->baudrate * 300;
RtcSettings . baudrate = APP_BAUDRATE ;
}
2022-08-05 14:25:39 +01:00
// AddLog(LOG_LEVEL_INFO, PSTR("DBG: energy_kWhtoday_ph[0] %d/%d"), RtcSettings.energy_kWhtoday_ph[0], Settings->energy_kWhtoday_ph[0]);
2020-04-19 13:18:12 +01:00
# ifdef ESP8266
ESP . rtcUserMemoryWrite ( 100 , ( uint32_t * ) & RtcSettings , sizeof ( RtcSettings ) ) ;
2020-11-28 11:46:17 +00:00
# endif // ESP8266
# ifdef ESP32
2020-04-19 13:18:12 +01:00
RtcDataSettings = RtcSettings ;
2020-11-28 11:46:17 +00:00
# endif // ESP32
2021-10-21 15:24:41 +01:00
2018-06-02 15:59:09 +01:00
rtc_settings_crc = GetRtcSettingsCrc ( ) ;
2017-02-28 15:01:48 +00:00
}
}
2021-01-05 10:49:13 +00:00
bool RtcSettingsLoad ( uint32_t update ) {
2020-04-19 13:18:12 +01:00
# ifdef ESP8266
ESP . rtcUserMemoryRead ( 100 , ( uint32_t * ) & RtcSettings , sizeof ( RtcSettings ) ) ; // 0x290
2020-11-28 11:46:17 +00:00
# endif // ESP8266
# ifdef ESP32
2020-04-19 13:18:12 +01:00
RtcSettings = RtcDataSettings ;
2020-11-28 11:46:17 +00:00
# endif // ESP32
2021-01-05 10:49:13 +00:00
bool read_valid = ( RTC_MEM_VALID = = RtcSettings . valid ) ;
if ( update ) {
if ( ! read_valid ) {
RtcSettingsSave ( ) ;
2017-05-17 21:49:22 +01:00
}
2017-02-28 15:01:48 +00:00
}
2021-01-05 10:49:13 +00:00
return read_valid ;
2017-02-28 15:01:48 +00:00
}
2021-01-22 10:54:15 +00:00
bool RtcSettingsValid ( void ) {
2017-10-18 17:22:34 +01:00
return ( RTC_MEM_VALID = = RtcSettings . valid ) ;
2017-02-28 15:01:48 +00:00
}
2018-09-04 15:22:34 +01:00
/********************************************************************************************/
uint32_t rtc_reboot_crc = 0 ;
2021-01-22 10:54:15 +00:00
uint32_t GetRtcRebootCrc ( void ) {
2018-09-04 15:22:34 +01:00
uint32_t crc = 0 ;
uint8_t * bytes = ( uint8_t * ) & RtcReboot ;
2020-04-19 12:08:04 +01:00
for ( uint32_t i = 0 ; i < sizeof ( RtcReboot ) ; i + + ) {
2018-09-04 15:22:34 +01:00
crc + = bytes [ i ] * ( i + 1 ) ;
}
return crc ;
}
2021-01-22 10:54:15 +00:00
void RtcRebootSave ( void ) {
2018-09-04 15:22:34 +01:00
if ( GetRtcRebootCrc ( ) ! = rtc_reboot_crc ) {
RtcReboot . valid = RTC_MEM_VALID ;
2020-04-19 13:18:12 +01:00
# ifdef ESP8266
ESP . rtcUserMemoryWrite ( 100 - sizeof ( RtcReboot ) , ( uint32_t * ) & RtcReboot , sizeof ( RtcReboot ) ) ;
2020-11-28 11:46:17 +00:00
# endif // ESP8266
# ifdef ESP32
2020-04-19 13:18:12 +01:00
RtcDataReboot = RtcReboot ;
2020-11-28 11:46:17 +00:00
# endif // ESP32
2018-09-04 15:22:34 +01:00
rtc_reboot_crc = GetRtcRebootCrc ( ) ;
}
}
2021-01-22 10:54:15 +00:00
void RtcRebootReset ( void ) {
2019-11-16 09:42:28 +00:00
RtcReboot . fast_reboot_count = 0 ;
RtcRebootSave ( ) ;
}
2021-01-22 10:54:15 +00:00
void RtcRebootLoad ( void ) {
2020-04-19 13:18:12 +01:00
# ifdef ESP8266
ESP . rtcUserMemoryRead ( 100 - sizeof ( RtcReboot ) , ( uint32_t * ) & RtcReboot , sizeof ( RtcReboot ) ) ; // 0x280
2020-11-28 11:46:17 +00:00
# endif // ESP8266
# ifdef ESP32
2020-04-19 13:18:12 +01:00
RtcReboot = RtcDataReboot ;
2020-11-28 11:46:17 +00:00
# endif // ESP32
2018-09-04 15:22:34 +01:00
if ( RtcReboot . valid ! = RTC_MEM_VALID ) {
2020-04-19 12:08:04 +01:00
memset ( & RtcReboot , 0 , sizeof ( RtcReboot ) ) ;
2018-09-04 15:22:34 +01:00
RtcReboot . valid = RTC_MEM_VALID ;
// RtcReboot.fast_reboot_count = 0; // Explicit by memset
RtcRebootSave ( ) ;
}
rtc_reboot_crc = GetRtcRebootCrc ( ) ;
}
2021-01-22 10:54:15 +00:00
bool RtcRebootValid ( void ) {
2018-09-04 15:22:34 +01:00
return ( RTC_MEM_VALID = = RtcReboot . valid ) ;
2018-08-30 13:27:33 +01:00
}
2017-02-19 16:49:17 +00:00
/*********************************************************************************************\
2021-01-11 16:56:18 +00:00
* ESP8266 Tasmota Flash usage offset from 0x40200000
2020-02-24 12:27:22 +00:00
*
2021-01-11 16:56:18 +00:00
* Tasmota 1 M Tasmota 2 M Tasmota 4 M - Flash usage
* 0x00000000 - 4 k Unzipped binary bootloader
* 0x00000FFF
*
* 0x00001000 - Unzipped binary code start
2020-02-24 12:27:22 +00:00
* : : : :
2021-01-11 16:56:18 +00:00
* 0x000 xxxxx - Unzipped binary code end
* 0x000 x1000 - First page used by Core OTA
2020-02-24 12:27:22 +00:00
* : : : :
2021-01-12 13:54:12 +00:00
* 0x000F2FFF 0x000F5FFF 0x000F5FFF
2021-01-11 16:56:18 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Next 32 k is overwritten by OTA
2021-01-12 13:54:12 +00:00
* 0x000F3000 0x000F6000 0x000F6000 - 4 k Tasmota Quick Power Cycle counter ( SETTINGS_LOCATION - CFG_ROTATES ) - First four bytes only
* 0x000F3FFF 0x000F6FFF 0x000F6FFF
* 0x000F4000 0x000F7000 0x000F7000 - 4 k First Tasmota rotating settings page
2020-02-24 12:27:22 +00:00
* : : : :
2021-01-12 13:54:12 +00:00
* 0x000FA000 0x000FD000 0x000FD000 - 4 k Last Tasmota rotating settings page = Last page used by Core OTA ( SETTINGS_LOCATION )
* 0x000FAFFF 0x000FDFFF 0x000FDFFF
2021-01-11 16:56:18 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2021-01-12 13:54:12 +00:00
* 0x000FE000 0x000FE000 - 3 k9 Not used
2021-01-11 16:56:18 +00:00
* 0x000FEFF0 0x000FEFF0 - 4 k1 Empty
* 0x000FFFFF 0x000FFFFF
2021-01-12 13:54:12 +00:00
*
2021-01-11 16:56:18 +00:00
* 0x000FB000 0x00100000 0x00100000 - 0 k , 980 k or 2980 k Core FS start ( LittleFS )
* 0x000FB000 0x001FA000 0x003FA000 - 0 k , 980 k or 2980 k Core FS end ( LittleFS )
* 0x001FAFFF 0x003FAFFF
*
2021-01-22 10:54:15 +00:00
* 0x000FB000 0x001FB000 0x003FB000 - 4 k Core EEPROM = Tasmota settings page during OTA and when no flash rotation is active ( EEPROM_LOCATION )
2021-01-11 16:56:18 +00:00
* 0x000FBFFF 0x001FBFFF 0x003FBFFF
*
* 0x000FC000 0x001FC000 0x003FC000 - 4 k SDK - Uses first 128 bytes for phy init data mirrored by Core in RAM . See core_esp8266_phy . cpp phy_init_data [ 128 ] = Core user_rf_cal_sector
* 0x000FD000 0x001FD000 0x003FD000 - 4 k SDK - Uses scattered bytes from 0x340 ( iTead use as settings storage from 0x000FD000 )
* 0x000FE000 0x001FE000 0x003FE000 - 4 k SDK - Uses scattered bytes from 0x340 ( iTead use as mirrored settings storage from 0x000FE000 )
* 0x000FF000 0x001FF000 0x0031F000 - 4 k SDK - Uses at least first 32 bytes of this page - Tasmota Zigbee persistence from 0x000FF800 to 0x000FFFFF
* 0x000FFFFF 0x001FFFFF 0x003FFFFF
2017-02-19 16:49:17 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
extern " C " {
# include "spi_flash.h"
}
2020-04-10 17:24:08 +01:00
# ifdef ESP8266
2022-01-27 20:30:05 +00:00
# include "eboot_command.h"
2021-01-11 16:56:18 +00:00
extern " C " uint32_t _FS_start ; // 1M = 0x402fb000, 2M = 0x40300000, 4M = 0x40300000
2021-01-12 13:54:12 +00:00
const uint32_t FLASH_FS_START = ( ( ( uint32_t ) & _FS_start - 0x40200000 ) / SPI_FLASH_SEC_SIZE ) ;
2021-01-22 10:54:15 +00:00
uint32_t SETTINGS_LOCATION = FLASH_FS_START - 1 ; // 0xFA, 0x0FF or 0x0FF
2019-10-30 15:51:13 +00:00
// From libraries/EEPROM/EEPROM.cpp EEPROMClass
2021-01-11 16:56:18 +00:00
extern " C " uint32_t _EEPROM_start ; // 1M = 0x402FB000, 2M = 0x403FB000, 4M = 0x405FB000
2021-01-22 10:54:15 +00:00
const uint32_t EEPROM_LOCATION = ( ( uint32_t ) & _EEPROM_start - 0x40200000 ) / SPI_FLASH_SEC_SIZE ; // 0xFB, 0x1FB or 0x3FB
2019-10-30 15:51:13 +00:00
2021-01-11 16:56:18 +00:00
# endif // ESP8266
2019-05-30 22:28:22 +01:00
2021-01-11 16:56:18 +00:00
# ifdef ESP32
2019-10-30 15:51:13 +00:00
2021-01-11 16:56:18 +00:00
// dummy defines
2021-01-22 10:54:15 +00:00
# define EEPROM_LOCATION (SPI_FLASH_SEC_SIZE * 200)
uint32_t SETTINGS_LOCATION = EEPROM_LOCATION ;
2020-04-10 17:24:08 +01:00
2021-01-11 16:56:18 +00:00
# endif // ESP32
2020-07-17 17:40:06 +01:00
2021-01-12 09:51:46 +00:00
const uint8_t CFG_ROTATES = 7 ; // Number of flash sectors used (handles uploads)
2017-02-19 16:49:17 +00:00
2021-01-22 10:54:15 +00:00
uint32_t settings_location = EEPROM_LOCATION ;
2019-09-07 17:32:11 +01:00
uint32_t settings_crc32 = 0 ;
2019-03-26 17:26:50 +00:00
uint8_t * settings_buffer = nullptr ;
2021-05-06 14:23:41 +01:00
uint8_t config_xor_on_set = CONFIG_FILE_XOR ;
2017-02-19 16:49:17 +00:00
2021-01-11 16:56:18 +00:00
void SettingsInit ( void ) {
2021-01-12 09:51:46 +00:00
if ( SETTINGS_LOCATION > 0xFA ) {
2021-01-12 13:54:12 +00:00
SETTINGS_LOCATION = 0xFD ; // Skip empty partition part and keep in first 1M
2021-01-12 09:51:46 +00:00
}
2021-01-11 16:56:18 +00:00
}
2021-05-06 14:23:41 +01:00
/*********************************************************************************************\
* Quick power cycle monitoring
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void UpdateQuickPowerCycle ( bool update ) {
# ifndef FIRMWARE_MINIMAL
2021-06-11 17:14:12 +01:00
if ( Settings - > flag3 . fast_power_cycle_disable ) { return ; } // SetOption65 - Disable fast power cycle detection for device reset
2021-05-06 14:23:41 +01:00
const uint32_t QPC_COUNT = 7 ; // Number of Power Cycles before Settings erase
const uint32_t QPC_SIGNATURE = 0xFFA55AFF ;
2022-02-27 16:45:05 +00:00
# ifdef USE_COUNTER
CounterInterruptDisable ( true ) ;
# endif
2020-04-10 17:24:08 +01:00
# ifdef ESP8266
2021-05-06 14:23:41 +01:00
const uint32_t qpc_sector = SETTINGS_LOCATION - CFG_ROTATES ;
const uint32_t qpc_location = qpc_sector * SPI_FLASH_SEC_SIZE ;
uint32_t qpc_buffer [ QPC_COUNT + 1 ] ;
ESP . flashRead ( qpc_location , ( uint32 * ) & qpc_buffer , sizeof ( qpc_buffer ) ) ;
if ( update & & ( QPC_SIGNATURE = = qpc_buffer [ 0 ] ) ) {
uint32_t counter = 1 ;
while ( ( 0 = = qpc_buffer [ counter ] ) & & ( counter < = QPC_COUNT ) ) { counter + + ; }
if ( QPC_COUNT = = counter ) { // 7 power cycles in a row
SettingsErase ( 3 ) ; // Quickly reset all settings including QuickPowerCycle flag
EspRestart ( ) ; // And restart
} else {
qpc_buffer [ 0 ] = 0 ;
ESP . flashWrite ( qpc_location + ( counter * 4 ) , ( uint32 * ) & qpc_buffer , 4 ) ;
AddLog ( LOG_LEVEL_INFO , PSTR ( " QPC: Count %d " ) , counter ) ;
}
}
else if ( ( qpc_buffer [ 0 ] ! = QPC_SIGNATURE ) | | ( 0 = = qpc_buffer [ 1 ] ) ) {
qpc_buffer [ 0 ] = QPC_SIGNATURE ;
// Assume flash is default all ones and setting a bit to zero does not need an erase
if ( ESP . flashEraseSector ( qpc_sector ) ) {
ESP . flashWrite ( qpc_location , ( uint32 * ) & qpc_buffer , 4 ) ;
AddLog ( LOG_LEVEL_INFO , PSTR ( " QPC: Reset " ) ) ;
2017-02-19 16:49:17 +00:00
}
}
2020-04-10 17:24:08 +01:00
# endif // ESP8266
2021-05-06 14:23:41 +01:00
# ifdef ESP32
uint32_t pc_register ;
QPCRead ( & pc_register , sizeof ( pc_register ) ) ;
if ( update & & ( ( pc_register & 0xFFFFFFF0 ) = = 0xFFA55AF0 ) ) {
uint32_t counter = pc_register & 0xF ; // Allow up to 15 cycles
if ( 0xF = = counter ) { counter = 0 ; }
counter + + ;
if ( QPC_COUNT = = counter ) { // 7 power cycles in a row
SettingsErase ( 3 ) ; // Quickly reset all settings including QuickPowerCycle flag
EspRestart ( ) ; // And restart
} else {
pc_register = 0xFFA55AF0 | counter ;
QPCWrite ( & pc_register , sizeof ( pc_register ) ) ;
AddLog ( LOG_LEVEL_INFO , PSTR ( " QPC: Count %d " ) , counter ) ;
}
2018-05-24 13:25:52 +01:00
}
2021-05-06 14:23:41 +01:00
else if ( pc_register ! = QPC_SIGNATURE ) {
pc_register = QPC_SIGNATURE ;
QPCWrite ( & pc_register , sizeof ( pc_register ) ) ;
AddLog ( LOG_LEVEL_INFO , PSTR ( " QPC: Reset " ) ) ;
2018-05-24 13:25:52 +01:00
}
2021-05-06 14:23:41 +01:00
# endif // ESP32
2022-02-27 16:45:05 +00:00
# ifdef USE_COUNTER
CounterInterruptDisable ( false ) ;
# endif
2021-05-06 14:23:41 +01:00
# endif // FIRMWARE_MINIMAL
2018-05-24 13:25:52 +01:00
}
2021-09-02 11:25:53 +01:00
# ifdef USE_EMERGENCY_RESET
/*********************************************************************************************\
* Emergency reset if Rx and Tx are tied together
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void EmergencyReset ( void ) {
Serial . begin ( 115200 ) ;
2021-10-14 16:32:43 +01:00
Serial . write ( 0xA5 ) ;
Serial . write ( 0x5A ) ;
2021-09-02 11:25:53 +01:00
delay ( 1 ) ;
if ( Serial . available ( ) = = 2 ) {
2021-10-14 16:32:43 +01:00
if ( ( Serial . read ( ) = = 0xA5 ) & & ( Serial . read ( ) = = 0x5A ) ) {
2021-09-02 11:25:53 +01:00
SettingsErase ( 3 ) ; // Reset all settings including QuickPowerCycle flag
do { // Wait for user to remove Rx Tx jumper and power cycle
Serial . write ( 0xA5 ) ;
delay ( 1000 ) ; // Satisfy SDK
} while ( Serial . read ( ) = = 0xA5 ) ; // Poll for removal of jumper
ESP_Restart ( ) ; // Restart to init default settings
}
}
2021-10-14 16:32:43 +01:00
Serial . println ( ) ;
Serial . flush ( ) ;
2021-10-02 13:04:32 +01:00
# ifdef ESP32
delay ( 10 ) ; // Allow time to cleanup queues - if not used hangs ESP32
Serial . end ( ) ;
delay ( 10 ) ; // Allow time to cleanup queues - if not used hangs ESP32
# endif // ESP32
2021-09-02 11:25:53 +01:00
}
# endif // USE_EMERGENCY_RESET
2021-05-06 14:23:41 +01:00
/*********************************************************************************************\
* Settings services
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-01-22 10:54:15 +00:00
uint16_t GetCfgCrc16 ( uint8_t * bytes , uint32_t size ) {
2018-06-02 15:59:09 +01:00
uint16_t crc = 0 ;
2017-02-19 16:49:17 +00:00
2019-08-25 13:58:45 +01:00
for ( uint32_t i = 0 ; i < size ; i + + ) {
2018-06-02 15:59:09 +01:00
if ( ( i < 14 ) | | ( i > 15 ) ) { crc + = bytes [ i ] * ( i + 1 ) ; } // Skip crc
2017-04-25 17:24:42 +01:00
}
2018-06-02 15:59:09 +01:00
return crc ;
2017-02-19 16:49:17 +00:00
}
2021-01-22 10:54:15 +00:00
uint16_t GetSettingsCrc ( void ) {
2019-09-07 17:32:11 +01:00
// Fix miscalculation if previous Settings was 3584 and current Settings is 4096 between 0x06060007 and 0x0606000A
2021-06-11 17:14:12 +01:00
uint32_t size = ( ( Settings - > version < 0x06060007 ) | | ( Settings - > version > 0x0606000A ) ) ? 3584 : sizeof ( TSettings ) ;
return GetCfgCrc16 ( ( uint8_t * ) Settings , size ) ;
2019-09-07 17:32:11 +01:00
}
2021-01-22 10:54:15 +00:00
uint32_t GetCfgCrc32 ( uint8_t * bytes , uint32_t size ) {
2019-09-05 15:56:02 +01:00
// https://create.stephan-brumme.com/crc32/#bitwise
uint32_t crc = 0 ;
2019-09-07 17:32:11 +01:00
while ( size - - ) {
2019-09-05 15:56:02 +01:00
crc ^ = * bytes + + ;
for ( uint32_t j = 0 ; j < 8 ; j + + ) {
crc = ( crc > > 1 ) ^ ( - int ( crc & 1 ) & 0xEDB88320 ) ;
}
}
return ~ crc ;
}
2021-01-22 10:54:15 +00:00
uint32_t GetSettingsCrc32 ( void ) {
2021-06-11 17:14:12 +01:00
return GetCfgCrc32 ( ( uint8_t * ) Settings , sizeof ( TSettings ) - 4 ) ; // Skip crc32
2019-09-07 17:32:11 +01:00
}
2021-01-22 10:54:15 +00:00
void SettingsSaveAll ( void ) {
2021-06-11 17:14:12 +01:00
if ( Settings - > flag . save_state ) {
Settings - > power = TasmotaGlobal . power ;
2017-11-21 15:06:51 +00:00
} else {
2021-06-11 17:14:12 +01:00
Settings - > power = 0 ;
2017-11-21 15:06:51 +00:00
}
2017-12-25 16:41:12 +00:00
XsnsCall ( FUNC_SAVE_BEFORE_RESTART ) ;
2019-05-19 13:59:07 +01:00
XdrvCall ( FUNC_SAVE_BEFORE_RESTART ) ;
2017-11-21 15:06:51 +00:00
SettingsSave ( 0 ) ;
}
2019-10-16 18:00:20 +01:00
/*********************************************************************************************\
2021-05-06 14:23:41 +01:00
* Settings backup and restore
2019-10-16 18:00:20 +01:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-05-06 14:23:41 +01:00
void SettingsBufferFree ( void ) {
if ( settings_buffer ! = nullptr ) {
free ( settings_buffer ) ;
settings_buffer = nullptr ;
}
}
2019-10-18 14:18:39 +01:00
2021-05-06 14:23:41 +01:00
bool SettingsBufferAlloc ( void ) {
SettingsBufferFree ( ) ;
2021-06-11 17:14:12 +01:00
if ( ! ( settings_buffer = ( uint8_t * ) malloc ( sizeof ( TSettings ) ) ) ) {
2021-05-06 14:23:41 +01:00
AddLog ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_APPLICATION D_UPLOAD_ERR_2 ) ) ; // Not enough (memory) space
return false ;
}
return true ;
}
2019-10-16 18:00:20 +01:00
2021-05-06 14:23:41 +01:00
String SettingsConfigFilename ( void ) {
char filename [ TOPSZ ] ;
char hostname [ sizeof ( TasmotaGlobal . hostname ) ] ;
snprintf_P ( filename , sizeof ( filename ) , PSTR ( " Config_%s_%s.dmp " ) , NoAlNumToUnderscore ( hostname , TasmotaGlobal . hostname ) , TasmotaGlobal . version ) ;
return String ( filename ) ;
}
2020-08-13 15:25:48 +01:00
2021-05-06 14:23:41 +01:00
uint32_t SettingsConfigBackup ( void ) {
if ( ! SettingsBufferAlloc ( ) ) { return 0 ; }
2021-06-11 17:14:12 +01:00
uint32_t cfg_crc32 = Settings - > cfg_crc32 ;
Settings - > cfg_crc32 = GetSettingsCrc32 ( ) ; // Calculate crc (again) as it might be wrong when savedata = 0 (#3918)
2021-05-06 14:23:41 +01:00
2021-06-11 17:14:12 +01:00
uint32_t config_len = sizeof ( TSettings ) ;
memcpy ( settings_buffer , Settings , config_len ) ;
2021-05-06 14:23:41 +01:00
2021-06-11 17:14:12 +01:00
Settings - > cfg_crc32 = cfg_crc32 ; // Restore crc in case savedata = 0 to make sure settings will be noted as changed
2021-05-06 14:23:41 +01:00
if ( config_xor_on_set ) {
for ( uint32_t i = 2 ; i < config_len ; i + + ) {
settings_buffer [ i ] ^ = ( config_xor_on_set + i ) ;
2019-10-16 18:00:20 +01:00
}
}
2021-05-06 14:23:41 +01:00
return config_len ;
}
bool SettingsConfigRestore ( void ) {
2021-06-11 17:14:12 +01:00
uint32_t config_len = sizeof ( TSettings ) ;
2021-05-06 14:23:41 +01:00
if ( config_xor_on_set ) {
for ( uint32_t i = 2 ; i < config_len ; i + + ) {
settings_buffer [ i ] ^ = ( config_xor_on_set + i ) ;
2019-11-21 10:12:53 +00:00
}
2020-08-13 15:25:48 +01:00
}
2021-05-06 14:23:41 +01:00
bool valid_settings = false ;
// unsigned long version; // 008
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 cfg_size; // 002
uint32_t buffer_size = settings_buffer [ 3 ] < < 8 | settings_buffer [ 2 ] ;
if ( buffer_version > 0x0606000A ) {
// uint32_t cfg_crc32; // FFC
uint32_t buffer_crc32 = settings_buffer [ 4095 ] < < 24 | settings_buffer [ 4094 ] < < 16 | settings_buffer [ 4093 ] < < 8 | settings_buffer [ 4092 ] ;
valid_settings = ( GetCfgCrc32 ( settings_buffer , buffer_size - 4 ) = = buffer_crc32 ) ;
2020-08-13 15:25:48 +01:00
} else {
2021-05-06 14:23:41 +01:00
// uint16_t cfg_crc; // 00E
uint16_t buffer_crc16 = settings_buffer [ 15 ] < < 8 | settings_buffer [ 14 ] ;
valid_settings = ( GetCfgCrc16 ( settings_buffer , buffer_size ) = = buffer_crc16 ) ;
2020-08-13 15:25:48 +01:00
}
2021-05-06 14:23:41 +01:00
} else {
valid_settings = ( settings_buffer [ 0 ] = = CONFIG_FILE_SIGN ) ;
2020-08-13 15:25:48 +01:00
}
2021-05-06 14:23:41 +01:00
if ( valid_settings ) {
// uint8_t config_version; // F36
2022-02-03 11:33:55 +00:00
# ifdef ESP8266
2021-06-11 17:14:12 +01:00
valid_settings = ( 0 = = settings_buffer [ 0xF36 ] ) ; // Settings->config_version
2021-05-06 14:23:41 +01:00
# endif // ESP8266
# ifdef ESP32
2022-02-08 18:05:54 +00:00
2022-02-08 15:30:10 +00:00
# ifdef CONFIG_IDF_TARGET_ESP32S3
2022-02-08 18:05:54 +00:00
valid_settings = ( 2 = = settings_buffer [ 0xF36 ] ) ; // Settings->config_version ESP32S3
# elif CONFIG_IDF_TARGET_ESP32S2
valid_settings = ( 3 = = settings_buffer [ 0xF36 ] ) ; // Settings->config_version ESP32S2
# elif CONFIG_IDF_TARGET_ESP32C3
valid_settings = ( 4 = = settings_buffer [ 0xF36 ] ) ; // Settings->config_version ESP32C3
2022-02-03 11:33:55 +00:00
# else
2022-02-08 18:05:54 +00:00
valid_settings = ( 1 = = settings_buffer [ 0xF36 ] ) ; // Settings->config_version ESP32 all other
2022-02-08 15:30:10 +00:00
# endif // CONFIG_IDF_TARGET_ESP32S3
2020-11-28 11:46:17 +00:00
# endif // ESP32
2021-05-06 14:23:41 +01:00
}
2020-08-13 15:25:48 +01:00
2021-05-06 14:23:41 +01:00
if ( valid_settings ) {
SettingsDefaultSet2 ( ) ;
2021-06-11 17:14:12 +01:00
memcpy ( ( char * ) Settings + 16 , settings_buffer + 16 , config_len - 16 ) ;
Settings - > version = buffer_version ; // Restore version and auto upgrade after restart
2021-05-06 14:23:41 +01:00
}
SettingsBufferFree ( ) ;
return valid_settings ;
2019-10-16 18:00:20 +01:00
}
2019-12-12 13:51:41 +00:00
/*********************************************************************************************\
2021-06-11 17:14:12 +01:00
* Config Settings - > text char array support
2019-12-12 13:51:41 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020-06-10 11:59:14 +01:00
uint32_t GetSettingsTextLen ( void ) {
2021-06-11 17:14:12 +01:00
char * position = Settings - > text_pool ;
2019-12-14 12:16:55 +00:00
for ( uint32_t size = 0 ; size < SET_MAX ; size + + ) {
while ( * position + + ! = ' \0 ' ) { }
2019-12-12 13:51:41 +00:00
}
2021-06-11 17:14:12 +01:00
return position - Settings - > text_pool ;
2019-12-12 13:51:41 +00:00
}
2020-06-10 11:59:14 +01:00
bool settings_text_mutex = false ;
uint32_t settings_text_busy_count = 0 ;
bool SettingsUpdateFinished ( void ) {
uint32_t wait_loop = 10 ;
while ( settings_text_mutex & & wait_loop ) { // Wait for any update to finish
yield ( ) ;
delayMicroseconds ( 1 ) ;
wait_loop - - ;
}
return ( wait_loop > 0 ) ; // true if finished
}
bool SettingsUpdateText ( uint32_t index , const char * replace_me ) {
2019-12-12 13:51:41 +00:00
if ( index > = SET_MAX ) {
return false ; // Setting not supported - internal error
}
2021-06-11 17:14:12 +01:00
// Make a copy first in case we use source from Settings->text
2020-05-04 19:00:05 +01:00
uint32_t replace_len = strlen_P ( replace_me ) ;
2019-12-14 12:16:55 +00:00
char replace [ replace_len + 1 ] ;
2020-05-04 19:00:05 +01:00
memcpy_P ( replace , replace_me , sizeof ( replace ) ) ;
2020-10-10 11:20:15 +01:00
uint32_t index_save = index ;
2019-12-12 13:51:41 +00:00
2019-12-21 14:37:36 +00:00
uint32_t start_pos = 0 ;
uint32_t end_pos = 0 ;
2021-06-11 17:14:12 +01:00
char * position = Settings - > text_pool ;
2019-12-21 14:37:36 +00:00
for ( uint32_t size = 0 ; size < SET_MAX ; size + + ) {
while ( * position + + ! = ' \0 ' ) { }
if ( 1 = = index ) {
2021-06-11 17:14:12 +01:00
start_pos = position - Settings - > text_pool ;
2019-12-21 14:37:36 +00:00
}
else if ( 0 = = index ) {
2021-06-11 17:14:12 +01:00
end_pos = position - Settings - > text_pool - 1 ;
2019-12-21 14:37:36 +00:00
}
index - - ;
2019-12-12 13:51:41 +00:00
}
2021-06-11 17:14:12 +01:00
uint32_t char_len = position - Settings - > text_pool ;
2019-12-21 14:37:36 +00:00
uint32_t current_len = end_pos - start_pos ;
int diff = replace_len - current_len ;
2021-01-23 15:26:23 +00:00
// AddLog(LOG_LEVEL_DEBUG, PSTR("TST: start %d, end %d, len %d, current %d, replace %d, diff %d"),
2019-12-21 14:37:36 +00:00
// start_pos, end_pos, char_len, current_len, replace_len, diff);
int too_long = ( char_len + diff ) - settings_text_size ;
if ( too_long > 0 ) {
2021-01-23 15:26:23 +00:00
AddLog ( LOG_LEVEL_INFO , PSTR ( D_LOG_CONFIG " Text overflow by %d char(s) " ) , too_long ) ;
2019-12-21 14:37:36 +00:00
return false ; // Replace text too long
}
2020-06-10 11:59:14 +01:00
if ( settings_text_mutex & & ! SettingsUpdateFinished ( ) ) {
settings_text_busy_count + + ;
} else {
settings_text_mutex = true ;
if ( diff ! = 0 ) {
2021-06-11 17:14:12 +01:00
// Shift Settings->text up or down
memmove_P ( Settings - > text_pool + start_pos + replace_len , Settings - > text_pool + end_pos , char_len - end_pos ) ;
2020-06-10 11:59:14 +01:00
}
// Replace text
2021-06-11 17:14:12 +01:00
memmove_P ( Settings - > text_pool + start_pos , replace , replace_len ) ;
2020-06-10 11:59:14 +01:00
// Fill for future use
2021-06-11 17:14:12 +01:00
memset ( Settings - > text_pool + char_len + diff , 0x00 , settings_text_size - char_len - diff ) ;
2020-06-10 11:59:14 +01:00
settings_text_mutex = false ;
2019-12-21 14:37:36 +00:00
}
2020-10-10 14:19:11 +01:00
# ifdef DEBUG_FUNC_SETTINGSUPDATETEXT
2021-01-23 15:26:23 +00:00
AddLog ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_CONFIG " CR %d/%d, Busy %d, Id %02d = \" %s \" " ) , GetSettingsTextLen ( ) , settings_text_size , settings_text_busy_count , index_save , replace ) ;
2020-10-10 14:19:11 +01:00
# else
2021-01-23 15:26:23 +00:00
AddLog ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_CONFIG " CR %d/%d, Busy %d " ) , GetSettingsTextLen ( ) , settings_text_size , settings_text_busy_count ) ;
2020-10-10 14:19:11 +01:00
# endif
2019-12-12 13:51:41 +00:00
return true ;
}
2021-01-22 10:54:15 +00:00
char * SettingsText ( uint32_t index ) {
2021-06-11 17:14:12 +01:00
char * position = Settings - > text_pool ;
2019-12-24 16:10:50 +00:00
if ( index > = SET_MAX ) {
position + = settings_text_size - 1 ; // Setting not supported - internal error - return empty string
} else {
2020-06-10 11:59:14 +01:00
SettingsUpdateFinished ( ) ;
2019-12-24 16:10:50 +00:00
for ( ; index > 0 ; index - - ) {
while ( * position + + ! = ' \0 ' ) { }
}
2019-12-12 13:51:41 +00:00
}
return position ;
}
2017-02-19 16:49:17 +00:00
/*********************************************************************************************\
2017-04-24 17:25:53 +01:00
* Config Save - Save parameters to Flash ONLY if any parameter has changed
2017-02-19 16:49:17 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2021-01-22 10:54:15 +00:00
void UpdateBackwardCompatibility ( void ) {
2020-03-29 16:41:31 +01:00
// Perform updates for backward compatibility
2021-06-11 17:14:12 +01:00
strlcpy ( Settings - > user_template_name , SettingsText ( SET_TEMPLATE_NAME ) , sizeof ( Settings - > user_template_name ) ) ;
2020-03-29 16:41:31 +01:00
}
2021-01-22 10:54:15 +00:00
uint32_t GetSettingsAddress ( void ) {
2017-10-18 17:22:34 +01:00
return settings_location * SPI_FLASH_SEC_SIZE ;
2017-06-25 22:01:41 +01:00
}
2021-01-22 10:54:15 +00:00
void SettingsSave ( uint8_t rotate ) {
2017-06-30 16:54:19 +01:00
/* Save configuration in eeprom or one of 7 slots below
2017-09-02 13:37:02 +01:00
*
2017-06-30 16:54:19 +01:00
* rotate 0 = Save in next flash slot
* rotate 1 = Save only in eeprom flash slot until SetOption12 0 or restart
2017-07-25 17:05:47 +01:00
* rotate 2 = Save in eeprom flash slot , erase next flash slots and continue depending on stop_flash_rotate
2017-06-30 16:54:19 +01:00
* stop_flash_rotate 0 = Allow flash slot rotation ( SetOption12 0 )
* stop_flash_rotate 1 = Allow only eeprom flash slot use ( SetOption12 1 )
*/
2019-02-08 13:55:45 +00:00
# ifndef FIRMWARE_MINIMAL
2021-02-01 15:51:41 +00:00
XsnsCall ( FUNC_SAVE_SETTINGS ) ;
XdrvCall ( FUNC_SAVE_SETTINGS ) ;
2020-03-29 16:41:31 +01:00
UpdateBackwardCompatibility ( ) ;
2019-09-07 17:32:11 +01:00
if ( ( GetSettingsCrc32 ( ) ! = settings_crc32 ) | | rotate ) {
2021-01-21 13:18:09 +00:00
if ( 1 = = rotate ) { // Use eeprom flash slot only and disable flash rotate from now on (upgrade)
2020-10-30 11:29:48 +00:00
TasmotaGlobal . stop_flash_rotate = 1 ;
2017-06-25 22:01:41 +01:00
}
2021-01-22 10:54:15 +00:00
if ( TasmotaGlobal . stop_flash_rotate | | ( 2 = = rotate ) ) { // Use eeprom flash slot and erase next flash slots if stop_flash_rotate is off (default)
settings_location = EEPROM_LOCATION ;
} else { // Rotate flash slots
if ( settings_location = = EEPROM_LOCATION ) {
2017-10-18 17:22:34 +01:00
settings_location = SETTINGS_LOCATION ;
2021-01-11 16:56:18 +00:00
} else {
settings_location - - ;
}
if ( settings_location < = ( SETTINGS_LOCATION - CFG_ROTATES ) ) {
2021-01-22 10:54:15 +00:00
settings_location = EEPROM_LOCATION ;
2017-06-19 21:54:49 +01:00
}
}
2019-09-07 17:32:11 +01:00
2021-06-11 17:14:12 +01:00
Settings - > save_flag + + ;
2019-09-05 15:56:02 +01:00
if ( UtcTime ( ) > START_VALID_TIME ) {
2021-06-11 17:14:12 +01:00
Settings - > cfg_timestamp = UtcTime ( ) ;
2019-09-05 15:56:02 +01:00
} else {
2021-06-11 17:14:12 +01:00
Settings - > cfg_timestamp + + ;
2019-09-05 15:56:02 +01:00
}
2021-06-11 17:14:12 +01:00
Settings - > cfg_size = sizeof ( TSettings ) ;
Settings - > cfg_crc = GetSettingsCrc ( ) ; // Keep for backward compatibility in case of fall-back just after upgrade
Settings - > cfg_crc32 = GetSettingsCrc32 ( ) ;
2022-04-07 14:06:21 +01:00
# ifdef USE_COUNTER
2022-02-25 19:23:20 +00:00
CounterInterruptDisable ( true ) ;
2022-02-25 19:44:33 +00:00
# endif
2020-04-10 17:24:08 +01:00
# ifdef ESP8266
2021-01-12 13:54:12 +00:00
# ifdef USE_UFILESYS
2021-06-11 17:14:12 +01:00
TfsSaveFile ( TASM_FILE_SETTINGS , ( const uint8_t * ) Settings , sizeof ( TSettings ) ) ;
2021-01-13 12:51:49 +00:00
# endif // USE_UFILESYS
2019-11-21 10:12:53 +00:00
if ( ESP . flashEraseSector ( settings_location ) ) {
2021-06-11 17:14:12 +01:00
ESP . flashWrite ( settings_location * SPI_FLASH_SEC_SIZE , ( uint32 * ) Settings , sizeof ( TSettings ) ) ;
2019-11-21 10:12:53 +00:00
}
2019-01-04 15:05:52 +00:00
2021-01-21 13:18:09 +00:00
if ( ! TasmotaGlobal . stop_flash_rotate & & rotate ) { // SetOption12 - (Settings) Switch between dynamic (0) or fixed (1) slot flash save location
2021-01-11 16:56:18 +00:00
for ( uint32_t i = 0 ; i < CFG_ROTATES ; i + + ) {
2021-01-21 13:18:09 +00:00
ESP . flashEraseSector ( SETTINGS_LOCATION - i ) ; // Delete previous configurations by resetting to 0xFF
2017-06-19 21:54:49 +01:00
delay ( 1 ) ;
}
}
2021-06-11 17:14:12 +01:00
AddLog ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d " ) , settings_location , Settings - > save_flag , sizeof ( TSettings ) ) ;
2020-11-28 11:46:17 +00:00
# endif // ESP8266
# ifdef ESP32
2021-06-11 17:14:12 +01:00
SettingsWrite ( Settings , sizeof ( TSettings ) ) ;
AddLog ( LOG_LEVEL_DEBUG , PSTR ( D_LOG_CONFIG " Saved, " D_COUNT " %d, " D_BYTES " %d " ) , Settings - > save_flag , sizeof ( TSettings ) ) ;
2020-11-28 11:46:17 +00:00
# endif // ESP32
2019-03-08 14:15:42 +00:00
2021-06-11 17:14:12 +01:00
settings_crc32 = Settings - > cfg_crc32 ;
2017-02-19 16:49:17 +00:00
}
2019-02-08 13:55:45 +00:00
# endif // FIRMWARE_MINIMAL
2017-10-18 17:22:34 +01:00
RtcSettingsSave ( ) ;
2022-04-07 14:06:21 +01:00
# ifdef USE_COUNTER
2022-02-25 19:23:20 +00:00
CounterInterruptDisable ( false ) ;
2022-02-25 19:31:42 +00:00
# endif
2017-02-19 16:49:17 +00:00
}
2020-08-13 12:04:28 +01:00
void SettingsLoad ( void ) {
2020-04-19 14:36:04 +01:00
# ifdef ESP8266
2021-01-12 16:18:56 +00:00
// Load configuration from optional file and flash (eeprom and 7 additonal slots) if first valid load does not stop_flash_rotate
2020-08-17 13:19:53 +01:00
// Activated with version 8.4.0.2 - Fails to read any config before version 6.6.0.11
2020-08-13 12:04:28 +01:00
settings_location = 0 ;
uint32_t save_flag = 0 ;
2021-01-12 16:18:56 +00:00
uint32_t max_slots = CFG_ROTATES + 1 ;
uint32_t flash_location ;
uint32_t slot = 1 ;
# ifdef USE_UFILESYS
2021-06-11 17:14:12 +01:00
if ( TfsLoadFile ( TASM_FILE_SETTINGS , ( uint8_t * ) Settings , sizeof ( TSettings ) ) ) {
2021-01-12 16:18:56 +00:00
flash_location = 1 ;
slot = 0 ;
}
2021-01-13 12:51:49 +00:00
# endif // USE_UFILESYS
2021-01-12 16:18:56 +00:00
while ( slot < = max_slots ) { // Read all config pages in search of valid and latest
if ( slot > 0 ) {
2021-01-22 10:54:15 +00:00
flash_location = ( 1 = = slot ) ? EEPROM_LOCATION : ( 2 = = slot ) ? SETTINGS_LOCATION : flash_location - 1 ;
2021-06-11 17:14:12 +01:00
ESP . flashRead ( flash_location * SPI_FLASH_SEC_SIZE , ( uint32 * ) Settings , sizeof ( TSettings ) ) ;
2021-01-12 16:18:56 +00:00
}
2021-06-11 17:14:12 +01:00
if ( ( Settings - > cfg_crc32 ! = 0xFFFFFFFF ) & & ( Settings - > cfg_crc32 ! = 0x00000000 ) & & ( Settings - > cfg_crc32 = = GetSettingsCrc32 ( ) ) ) {
if ( Settings - > save_flag > save_flag ) { // Find latest page based on incrementing save_flag
save_flag = Settings - > save_flag ;
2019-01-30 15:27:17 +00:00
settings_location = flash_location ;
2021-06-11 17:14:12 +01:00
if ( Settings - > flag . stop_flash_rotate & & ( 1 = = slot ) ) { // Stop if only eeprom area should be used and it is valid
2019-01-30 15:27:17 +00:00
break ;
}
}
2017-02-19 16:49:17 +00:00
}
2021-01-12 16:18:56 +00:00
slot + + ;
2017-06-19 21:54:49 +01:00
delay ( 1 ) ;
}
2019-01-30 15:27:17 +00:00
if ( settings_location > 0 ) {
2021-01-12 13:54:12 +00:00
# ifdef USE_UFILESYS
2021-01-12 16:18:56 +00:00
if ( 1 = = settings_location ) {
2021-06-11 17:14:12 +01:00
TfsLoadFile ( TASM_FILE_SETTINGS , ( uint8_t * ) Settings , sizeof ( TSettings ) ) ;
AddLog ( LOG_LEVEL_NONE , PSTR ( D_LOG_CONFIG " Loaded from File, " D_COUNT " %lu " ) , Settings - > save_flag ) ;
2021-01-12 16:18:56 +00:00
} else
2021-01-13 12:51:49 +00:00
# endif // USE_UFILESYS
2021-01-12 16:18:56 +00:00
{
2021-06-11 17:14:12 +01:00
ESP . flashRead ( settings_location * SPI_FLASH_SEC_SIZE , ( uint32 * ) Settings , sizeof ( TSettings ) ) ;
AddLog ( LOG_LEVEL_NONE , PSTR ( D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu " ) , settings_location , Settings - > save_flag ) ;
2021-01-12 16:18:56 +00:00
}
}
2020-11-28 11:46:17 +00:00
# endif // ESP8266
2021-10-18 14:41:37 +01:00
2020-11-28 11:46:17 +00:00
# ifdef ESP32
2021-06-11 17:14:12 +01:00
uint32_t source = SettingsRead ( Settings , sizeof ( TSettings ) ) ;
2021-10-18 14:41:37 +01:00
if ( source ) {
settings_location = 1 ;
if ( Settings - > cfg_holder = = ( uint16_t ) CFG_HOLDER ) {
2021-12-12 17:04:46 +00:00
AddLog ( LOG_LEVEL_NONE , PSTR ( D_LOG_CONFIG " Loaded from %s, " D_COUNT " %lu " ) , ( 2 = = source ) ? " File " : " NVS " , Settings - > save_flag ) ;
2021-10-18 14:41:37 +01:00
}
}
2020-11-28 11:46:17 +00:00
# endif // ESP32
2017-09-02 13:37:02 +01:00
2019-02-08 13:55:45 +00:00
# ifndef FIRMWARE_MINIMAL
2021-06-11 17:14:12 +01:00
if ( ( 0 = = settings_location ) | | ( Settings - > cfg_holder ! = ( uint16_t ) CFG_HOLDER ) ) { // Init defaults if cfg_holder differs from user settings in my_user_config.h
2021-07-01 14:19:35 +01:00
// if ((0 == settings_location) || (Settings->cfg_size != sizeof(TSettings)) || (Settings->cfg_holder != (uint16_t)CFG_HOLDER)) { // Init defaults if cfg_holder differs from user settings in my_user_config.h
2021-01-13 12:51:49 +00:00
# ifdef USE_UFILESYS
2021-06-11 17:14:12 +01:00
if ( TfsLoadFile ( TASM_FILE_SETTINGS_LKG , ( uint8_t * ) Settings , sizeof ( TSettings ) ) & & ( Settings - > cfg_crc32 = = GetSettingsCrc32 ( ) ) ) {
2021-01-13 12:51:49 +00:00
settings_location = 1 ;
2021-06-11 17:14:12 +01:00
AddLog ( LOG_LEVEL_NONE , PSTR ( D_LOG_CONFIG " Loaded from LKG File, " D_COUNT " %lu " ) , Settings - > save_flag ) ;
2021-01-13 12:51:49 +00:00
} else
# endif // USE_UFILESYS
{
SettingsDefault ( ) ;
}
2019-01-30 15:27:17 +00:00
}
2019-09-07 17:32:11 +01:00
settings_crc32 = GetSettingsCrc32 ( ) ;
2019-02-08 13:55:45 +00:00
# endif // FIRMWARE_MINIMAL
2017-02-28 15:01:48 +00:00
2021-01-05 10:49:13 +00:00
RtcSettingsLoad ( 1 ) ;
2017-02-19 16:49:17 +00:00
}
2020-11-06 20:37:38 +00:00
// Used in TLS - returns the timestamp of the last Flash settings write
uint32_t CfgTime ( void ) {
2021-06-11 17:14:12 +01:00
return Settings - > cfg_timestamp ;
2020-11-06 20:37:38 +00:00
}
2020-04-11 08:54:13 +01:00
# ifdef ESP8266
2021-01-22 10:54:15 +00:00
void SettingsErase ( uint8_t type ) {
2018-02-24 15:37:33 +00:00
/*
2019-11-15 14:42:10 +00:00
For Arduino core and SDK :
2022-09-17 14:53:58 +01:00
Erase only works from flash start address to SDK recognized flash end address ( flashchip - > chip_size = ESP_getFlashChipSize ) .
2019-11-14 14:57:52 +00:00
Addresses above SDK recognized size ( up to ESP . getFlashChipRealSize ) are not accessable .
2019-11-15 14:42:10 +00:00
For Esptool :
2019-11-14 14:57:52 +00:00
The only way to erase whole flash is esptool which uses direct SPI writes to flash .
2019-11-15 15:58:22 +00:00
The default erase function is EspTool ( EsptoolErase )
2019-11-15 14:42:10 +00:00
2021-01-12 13:54:12 +00:00
0 = Erase from program end until end of flash as seen by SDK including optional filesystem
1 = Erase 16 k SDK parameter area near end of flash as seen by SDK ( 0x0 XFCxxx - 0x0 XFFFFF ) solving possible wifi errors
2 = Erase from program end until end of flash as seen by SDK excluding optional filesystem
2019-11-18 10:17:43 +00:00
3 = Erase Tasmota and SDK parameter area ( 0x0F3 xxx - 0x0FFFFF )
2020-02-25 15:49:19 +00:00
4 = Erase SDK parameter area used for wifi calibration ( 0x0FC xxx - 0x0FCFFF )
2018-02-24 15:37:33 +00:00
*/
2019-02-08 13:55:45 +00:00
# ifndef FIRMWARE_MINIMAL
2021-01-12 13:54:12 +00:00
// Reset 2 = Erase all flash from program end to end of physical flash
2017-02-19 16:49:17 +00:00
uint32_t _sectorStart = ( ESP . getSketchSize ( ) / SPI_FLASH_SEC_SIZE ) + 1 ;
2019-11-18 10:17:43 +00:00
uint32_t _sectorEnd = ESP . getFlashChipRealSize ( ) / SPI_FLASH_SEC_SIZE ; // Flash size as reported by hardware
2021-01-12 13:54:12 +00:00
if ( 1 = = type ) { // Reset 3 = SDK parameter area
2019-11-14 14:57:52 +00:00
// source Esp.cpp and core_esp8266_phy.cpp
2021-01-12 13:54:12 +00:00
_sectorStart = ( ESP . getFlashChipSize ( ) / SPI_FLASH_SEC_SIZE ) - 4 ;
2020-02-24 12:27:22 +00:00
}
2021-01-12 13:54:12 +00:00
else if ( 2 = = type ) { // Reset 5, 6 = Erase all flash from program end to end of physical flash but skip filesystem
2020-02-25 15:49:19 +00:00
/*
2021-01-12 13:54:12 +00:00
# ifdef USE_UFILESYS
TfsDeleteFile ( TASM_FILE_SETTINGS ) ; // Not needed as it is recreated by set defaults before restart
# endif
2020-02-25 15:49:19 +00:00
*/
2021-01-12 13:54:12 +00:00
EsptoolErase ( _sectorStart , FLASH_FS_START ) ;
2021-01-22 10:54:15 +00:00
_sectorStart = EEPROM_LOCATION ;
2022-09-17 14:53:58 +01:00
_sectorEnd = ESP_getFlashChipSize ( ) / SPI_FLASH_SEC_SIZE ; // Flash size as seen by SDK
2021-01-12 13:54:12 +00:00
}
else if ( 3 = = type ) { // QPC Reached = QPC and Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
# ifdef USE_UFILESYS
TfsDeleteFile ( TASM_FILE_SETTINGS ) ;
# endif
EsptoolErase ( SETTINGS_LOCATION - CFG_ROTATES , SETTINGS_LOCATION + 1 ) ;
2021-01-22 10:54:15 +00:00
_sectorStart = EEPROM_LOCATION ;
2021-01-12 13:54:12 +00:00
_sectorEnd = ESP . getFlashChipSize ( ) / SPI_FLASH_SEC_SIZE ; // Flash size as seen by SDK
}
else if ( 4 = = type ) { // WIFI_FORCE_RF_CAL_ERASE = SDK wifi calibration
2021-01-22 10:54:15 +00:00
_sectorStart = EEPROM_LOCATION + 1 ; // SDK phy area and Core calibration sector (0x0XFC000)
2021-01-12 13:54:12 +00:00
_sectorEnd = _sectorStart + 1 ; // SDK end of phy area and Core calibration sector (0x0XFCFFF)
2020-02-26 12:45:46 +00:00
}
2021-01-12 13:54:12 +00:00
EsptoolErase ( _sectorStart , _sectorEnd ) ; // Esptool - erases flash completely
2019-02-08 13:55:45 +00:00
# endif // FIRMWARE_MINIMAL
2017-02-19 16:49:17 +00:00
}
2020-04-11 08:54:13 +01:00
# endif // ESP8266
2017-02-19 16:49:17 +00:00
2021-01-22 10:54:15 +00:00
void SettingsSdkErase ( void ) {
2021-01-12 13:54:12 +00:00
WiFi . disconnect ( false ) ; // Delete SDK wifi config
2018-02-24 15:37:33 +00:00
SettingsErase ( 1 ) ;
delay ( 1000 ) ;
}
2017-02-19 16:49:17 +00:00
/********************************************************************************************/
2021-01-22 10:54:15 +00:00
void SettingsDefault ( void ) {
2021-01-23 15:26:23 +00:00
AddLog ( LOG_LEVEL_NONE , PSTR ( D_LOG_CONFIG D_USE_DEFAULTS ) ) ;
2017-10-18 17:22:34 +01:00
SettingsDefaultSet1 ( ) ;
SettingsDefaultSet2 ( ) ;
2021-05-09 12:09:53 +01:00
SettingsDefaultSet3 ( ) ;
2017-10-18 17:22:34 +01:00
SettingsSave ( 2 ) ;
2017-05-03 17:19:13 +01:00
}
2021-01-22 10:54:15 +00:00
void SettingsDefaultSet1 ( void ) {
2021-06-11 17:14:12 +01:00
memset ( Settings , 0x00 , sizeof ( TSettings ) ) ;
Settings - > cfg_holder = ( uint16_t ) CFG_HOLDER ;
Settings - > cfg_size = sizeof ( TSettings ) ;
// Settings->save_flag = 0;
Settings - > version = VERSION ;
// Settings->bootcount = 0;
// Settings->cfg_crc = 0;
2017-02-19 16:49:17 +00:00
}
2017-09-02 13:37:02 +01:00
2020-10-21 10:19:59 +01:00
// default Fingerprints in PROGMEM
const uint8_t default_fingerprint1 [ ] PROGMEM = { MQTT_FINGERPRINT1 } ;
const uint8_t default_fingerprint2 [ ] PROGMEM = { MQTT_FINGERPRINT2 } ;
2021-01-22 10:54:15 +00:00
void SettingsDefaultSet2 ( void ) {
2021-06-11 17:14:12 +01:00
memset ( ( char * ) Settings + 16 , 0x00 , sizeof ( TSettings ) - 16 ) ;
2017-10-18 17:22:34 +01:00
2020-05-06 18:21:04 +01:00
// this little trick allows GCC to optimize the assignment by grouping values and doing only ORs
2021-04-30 14:42:57 +01:00
SOBitfield flag = { 0 } ;
SOBitfield3 flag3 = { 0 } ;
SOBitfield4 flag4 = { 0 } ;
SOBitfield5 flag5 = { 0 } ;
2022-09-21 08:35:40 +01:00
SOBitfield6 flag6 = { 0 } ;
2021-04-19 11:25:53 +01:00
SysMBitfield1 flag2 = { 0 } ;
SysMBitfield2 mbflag2 = { 0 } ;
2020-05-06 18:21:04 +01:00
2020-04-21 14:53:45 +01:00
# ifdef ESP8266
2021-06-11 17:14:12 +01:00
Settings - > gpio16_converted = 0xF5A0 ;
// Settings->config_version = 0; // ESP8266 (Has been 0 for long time)
2020-04-21 14:53:45 +01:00
# endif // ESP8266
# ifdef ESP32
2022-02-08 15:30:10 +00:00
# ifdef CONFIG_IDF_TARGET_ESP32S3
Settings - > config_version = 2 ; // ESP32S3
2022-02-08 18:05:54 +00:00
# elif CONFIG_IDF_TARGET_ESP32S2
Settings - > config_version = 3 ; // ESP32S2
# elif CONFIG_IDF_TARGET_ESP32C3
Settings - > config_version = 4 ; // ESP32C3
2022-02-03 11:33:55 +00:00
# else
2021-06-11 17:14:12 +01:00
Settings - > config_version = 1 ; // ESP32
2022-02-08 15:30:10 +00:00
# endif // CONFIG_IDF_TARGET_ESP32S3
2020-04-21 14:53:45 +01:00
# endif // ESP32
2020-05-06 18:21:04 +01:00
flag . stop_flash_rotate | = APP_FLASH_CYCLE ;
flag . global_state | = APP_ENABLE_LEDLINK ;
flag3 . sleep_normal | = APP_NORMAL_SLEEP ;
flag3 . no_power_feedback | = APP_NO_RELAY_SCAN ;
flag3 . fast_power_cycle_disable | = APP_DISABLE_POWERCYCLE ;
flag3 . bootcount_update | = DEEPSLEEP_BOOTCOUNT ;
2021-03-02 21:47:40 +00:00
flag3 . mqtt_buttons | = MQTT_BUTTONS ;
2021-06-11 17:14:12 +01:00
Settings - > save_data = SAVE_DATA ;
Settings - > param [ P_BACKLOG_DELAY ] = MIN_BACKLOG_DELAY ;
Settings - > param [ P_BOOT_LOOP_OFFSET ] = BOOT_LOOP_OFFSET ; // SetOption36
Settings - > param [ P_RGB_REMAP ] = RGB_REMAP_RGBW ;
Settings - > sleep = APP_SLEEP ;
if ( Settings - > sleep < 50 ) {
Settings - > sleep = 50 ; // Default to 50 for sleep, for now
2018-12-01 17:53:42 +00:00
}
2018-06-02 15:59:09 +01:00
// Module
2020-06-22 21:36:54 +01:00
flag . interlock | = APP_INTERLOCK_MODE ;
2021-06-11 17:14:12 +01:00
Settings - > interlock [ 0 ] = APP_INTERLOCK_GROUP_1 ;
Settings - > interlock [ 1 ] = APP_INTERLOCK_GROUP_2 ;
Settings - > interlock [ 2 ] = APP_INTERLOCK_GROUP_3 ;
Settings - > interlock [ 3 ] = APP_INTERLOCK_GROUP_4 ;
Settings - > module = MODULE ;
Settings - > fallback_module = FALLBACK_MODULE ;
2019-02-11 18:21:49 +00:00
ModuleDefault ( WEMOS ) ;
2021-06-11 17:14:12 +01:00
// for (uint32_t i = 0; i < nitems(Settings->my_gp.io); i++) { Settings->my_gp.io[i] = GPIO_NONE; }
2020-05-04 19:00:05 +01:00
SettingsUpdateText ( SET_FRIENDLYNAME1 , PSTR ( FRIENDLY_NAME ) ) ;
SettingsUpdateText ( SET_FRIENDLYNAME2 , PSTR ( FRIENDLY_NAME " 2 " ) ) ;
SettingsUpdateText ( SET_FRIENDLYNAME3 , PSTR ( FRIENDLY_NAME " 3 " ) ) ;
SettingsUpdateText ( SET_FRIENDLYNAME4 , PSTR ( FRIENDLY_NAME " 4 " ) ) ;
2021-04-12 20:16:13 +01:00
# ifdef DEVICE_NAME
SettingsUpdateText ( SET_DEVICENAME , PSTR ( DEVICE_NAME ) ) ;
# else
2020-05-17 16:10:17 +01:00
SettingsUpdateText ( SET_DEVICENAME , SettingsText ( SET_FRIENDLYNAME1 ) ) ;
2021-04-12 20:16:13 +01:00
# endif
2020-05-04 19:00:05 +01:00
SettingsUpdateText ( SET_OTAURL , PSTR ( OTA_URL ) ) ;
2018-06-02 15:59:09 +01:00
// Power
2020-05-06 18:21:04 +01:00
flag . save_state | = SAVE_STATE ;
2021-06-11 17:14:12 +01:00
Settings - > power = APP_POWER ;
Settings - > poweronstate = APP_POWERON_STATE ;
Settings - > blinktime = APP_BLINKTIME ;
Settings - > blinkcount = APP_BLINKCOUNT ;
Settings - > ledstate = APP_LEDSTATE ;
Settings - > ledmask = APP_LEDMASK ;
// Settings->ledpwm_off = 0;
Settings - > ledpwm_on = 255 ;
// Settings->ledpwm_mask = 0;
Settings - > pulse_timer [ 0 ] = APP_PULSETIME ;
// for (uint32_t i = 1; i < MAX_PULSETIMERS; i++) { Settings->pulse_timer[i] = 0; }
2022-07-16 13:32:18 +01:00
Settings - > param [ P_BISTABLE_PULSE ] = APP_BISTABLE_PULSE ;
2018-06-02 15:59:09 +01:00
// Serial
2021-06-11 17:14:12 +01:00
Settings - > serial_config = TS_SERIAL_8N1 ;
Settings - > baudrate = APP_BAUDRATE / 300 ;
Settings - > sbaudrate = SOFT_BAUDRATE / 300 ;
Settings - > serial_delimiter = 0xff ;
Settings - > seriallog_level = SERIAL_LOG_LEVEL ;
2018-06-02 15:59:09 +01:00
2020-06-15 17:27:04 +01:00
// Ethernet
flag4 . network_ethernet | = 1 ;
2020-06-16 17:36:49 +01:00
# ifdef ESP32
2021-06-11 17:14:12 +01:00
Settings - > eth_type = ETH_TYPE ;
Settings - > eth_clk_mode = ETH_CLKMODE ;
Settings - > eth_address = ETH_ADDRESS ;
2020-11-28 11:46:17 +00:00
# endif // ESP32
2020-06-15 17:27:04 +01:00
2018-06-02 15:59:09 +01:00
// Wifi
2020-06-15 17:27:04 +01:00
flag4 . network_wifi | = 1 ;
2020-05-06 18:21:04 +01:00
flag3 . use_wifi_scan | = WIFI_SCAN_AT_RESTART ;
flag3 . use_wifi_rescan | = WIFI_SCAN_REGULARLY ;
2021-06-11 17:14:12 +01:00
Settings - > wifi_output_power = 170 ;
2022-06-19 16:57:43 +01:00
Settings - > dns_timeout = DNS_TIMEOUT ;
2021-06-11 17:14:12 +01:00
Settings - > param [ P_ARP_GRATUITOUS ] = WIFI_ARP_INTERVAL ;
ParseIPv4 ( & Settings - > ipv4_address [ 0 ] , PSTR ( WIFI_IP_ADDRESS ) ) ;
ParseIPv4 ( & Settings - > ipv4_address [ 1 ] , PSTR ( WIFI_GATEWAY ) ) ;
ParseIPv4 ( & Settings - > ipv4_address [ 2 ] , PSTR ( WIFI_SUBNETMASK ) ) ;
ParseIPv4 ( & Settings - > ipv4_address [ 3 ] , PSTR ( WIFI_DNS ) ) ;
2021-07-29 15:57:04 +01:00
ParseIPv4 ( & Settings - > ipv4_address [ 4 ] , PSTR ( WIFI_DNS2 ) ) ;
2021-08-01 16:51:54 +01:00
ParseIPv4 ( & Settings - > ipv4_rgx_address , PSTR ( WIFI_RGX_IP_ADDRESS ) ) ;
ParseIPv4 ( & Settings - > ipv4_rgx_subnetmask , PSTR ( WIFI_RGX_SUBNETMASK ) ) ;
2021-06-11 17:14:12 +01:00
Settings - > sta_config = WIFI_CONFIG_TOOL ;
// Settings->sta_active = 0;
2020-05-04 19:00:05 +01:00
SettingsUpdateText ( SET_STASSID1 , PSTR ( STA_SSID1 ) ) ;
SettingsUpdateText ( SET_STASSID2 , PSTR ( STA_SSID2 ) ) ;
SettingsUpdateText ( SET_STAPWD1 , PSTR ( STA_PASS1 ) ) ;
SettingsUpdateText ( SET_STAPWD2 , PSTR ( STA_PASS2 ) ) ;
2019-12-16 14:13:57 +00:00
SettingsUpdateText ( SET_HOSTNAME , WIFI_HOSTNAME ) ;
2021-08-01 16:51:54 +01:00
SettingsUpdateText ( SET_RGX_SSID , PSTR ( WIFI_RGX_SSID ) ) ;
SettingsUpdateText ( SET_RGX_PASSWORD , PSTR ( WIFI_RGX_PASSWORD ) ) ;
2021-08-02 01:25:32 +01:00
Settings - > sbflag1 . range_extender = WIFI_RGX_STATE ;
Settings - > sbflag1 . range_extender_napt = WIFI_RGX_NAPT ;
2022-04-19 16:26:57 +01:00
flag5 . wifi_no_sleep | = WIFI_NO_SLEEP ;
2018-06-02 15:59:09 +01:00
// Syslog
2020-05-04 19:00:05 +01:00
SettingsUpdateText ( SET_SYSLOG_HOST , PSTR ( SYS_LOG_HOST ) ) ;
2021-06-11 17:14:12 +01:00
Settings - > syslog_port = SYS_LOG_PORT ;
Settings - > syslog_level = SYS_LOG_LEVEL ;
2018-06-02 15:59:09 +01:00
// Webserver
2020-05-06 18:21:04 +01:00
flag2 . emulation | = EMULATION ;
2020-08-30 14:44:28 +01:00
flag4 . alexa_gen_1 | = EMULATION_HUE_1ST_GEN ;
2020-05-06 18:21:04 +01:00
flag3 . gui_hostname_ip | = GUI_SHOW_HOSTNAME ;
flag3 . mdns_enabled | = MDNS_ENABLED ;
2021-06-11 17:14:12 +01:00
Settings - > webserver = WEB_SERVER ;
Settings - > weblog_level = WEB_LOG_LEVEL ;
2020-05-04 19:00:05 +01:00
SettingsUpdateText ( SET_WEBPWD , PSTR ( WEB_PASSWORD ) ) ;
SettingsUpdateText ( SET_CORS , PSTR ( CORS_DOMAIN ) ) ;
2021-09-01 01:25:06 +01:00
# ifdef DISABLE_REFERER_CHK
flag5 . disable_referer_chk | = false ;
# else
flag5 . disable_referer_chk | = true ;
# endif
2018-06-02 15:59:09 +01:00
// Button
2020-05-06 18:21:04 +01:00
flag . button_restrict | = KEY_DISABLE_MULTIPRESS ;
flag . button_swap | = KEY_SWAP_DOUBLE_PRESS ;
flag . button_single | = KEY_ONLY_SINGLE_PRESS ;
2021-06-11 17:14:12 +01:00
Settings - > param [ P_HOLD_TIME ] = KEY_HOLD_TIME ; // Default 4 seconds hold time
2022-09-27 14:55:45 +01:00
# ifdef ESP32
2022-09-27 14:36:35 +01:00
Settings - > touch_threshold = ESP32_TOUCH_THRESHOLD ;
2022-09-27 14:55:45 +01:00
# endif
2017-10-18 17:22:34 +01:00
2018-06-02 15:59:09 +01:00
// Switch
2021-06-11 17:14:12 +01:00
for ( uint32_t i = 0 ; i < MAX_SWITCHES_SET ; i + + ) { Settings - > switchmode [ i ] = SWITCH_MODE ; }
2018-06-02 15:59:09 +01:00
// MQTT
2020-05-06 18:21:04 +01:00
flag . mqtt_enabled | = MQTT_USE ;
flag . mqtt_response | = MQTT_RESULT_COMMAND ;
flag . mqtt_offline | = MQTT_LWT_MESSAGE ;
flag . mqtt_power_retain | = MQTT_POWER_RETAIN ;
flag . mqtt_button_retain | = MQTT_BUTTON_RETAIN ;
flag . mqtt_switch_retain | = MQTT_SWITCH_RETAIN ;
flag . mqtt_sensor_retain | = MQTT_SENSOR_RETAIN ;
2021-02-22 08:11:36 +00:00
flag5 . mqtt_info_retain | = MQTT_INFO_RETAIN ;
flag5 . mqtt_state_retain | = MQTT_STATE_RETAIN ;
2022-08-19 13:24:55 +01:00
flag5 . mqtt_status_retain | = MQTT_STATUS_RETAIN ;
2021-03-02 21:47:40 +00:00
flag5 . mqtt_switches | = MQTT_SWITCHES ;
2022-05-03 21:16:24 +01:00
flag5 . mqtt_persistent | = ~ MQTT_CLEAN_SESSION ;
2022-09-21 20:42:53 +01:00
flag6 . mqtt_disable_sserialrec | = MQTT_DISABLE_SSERIALRECEIVED ;
2020-05-06 18:21:04 +01:00
// flag.mqtt_serial |= 0;
flag . device_index_enable | = MQTT_POWER_FORMAT ;
flag3 . time_append_timezone | = MQTT_APPEND_TIMEZONE ;
flag3 . button_switch_force_local | = MQTT_BUTTON_SWITCH_FORCE_LOCAL ;
flag3 . no_hold_retain | = MQTT_NO_HOLD_RETAIN ;
flag3 . use_underscore | = MQTT_INDEX_SEPARATOR ;
flag3 . grouptopic_mode | = MQTT_GROUPTOPIC_FORMAT ;
2019-12-16 14:13:57 +00:00
SettingsUpdateText ( SET_MQTT_HOST , MQTT_HOST ) ;
2021-06-11 17:14:12 +01:00
Settings - > mqtt_port = MQTT_PORT ;
2021-01-18 20:48:04 +00:00
SettingsUpdateText ( SET_MQTT_CLIENT , PSTR ( MQTT_CLIENT_ID ) ) ;
SettingsUpdateText ( SET_MQTT_USER , PSTR ( MQTT_USER ) ) ;
SettingsUpdateText ( SET_MQTT_PWD , PSTR ( MQTT_PASS ) ) ;
SettingsUpdateText ( SET_MQTT_TOPIC , PSTR ( MQTT_TOPIC ) ) ;
SettingsUpdateText ( SET_MQTT_BUTTON_TOPIC , PSTR ( MQTT_BUTTON_TOPIC ) ) ;
SettingsUpdateText ( SET_MQTT_SWITCH_TOPIC , PSTR ( MQTT_SWITCH_TOPIC ) ) ;
SettingsUpdateText ( SET_MQTT_GRP_TOPIC , PSTR ( MQTT_GRPTOPIC ) ) ;
SettingsUpdateText ( SET_MQTT_FULLTOPIC , PSTR ( MQTT_FULLTOPIC ) ) ;
2021-06-11 17:14:12 +01:00
Settings - > mqtt_retry = MQTT_RETRY_SECS ;
2021-01-18 20:48:04 +00:00
SettingsUpdateText ( SET_MQTTPREFIX1 , PSTR ( SUB_PREFIX ) ) ;
SettingsUpdateText ( SET_MQTTPREFIX2 , PSTR ( PUB_PREFIX ) ) ;
SettingsUpdateText ( SET_MQTTPREFIX3 , PSTR ( PUB_PREFIX2 ) ) ;
SettingsUpdateText ( SET_STATE_TXT1 , PSTR ( MQTT_STATUS_OFF ) ) ;
SettingsUpdateText ( SET_STATE_TXT2 , PSTR ( MQTT_STATUS_ON ) ) ;
SettingsUpdateText ( SET_STATE_TXT3 , PSTR ( MQTT_CMND_TOGGLE ) ) ;
SettingsUpdateText ( SET_STATE_TXT4 , PSTR ( MQTT_CMND_HOLD ) ) ;
2021-06-11 17:14:12 +01:00
memcpy_P ( Settings - > mqtt_fingerprint [ 0 ] , default_fingerprint1 , sizeof ( default_fingerprint1 ) ) ;
memcpy_P ( Settings - > mqtt_fingerprint [ 1 ] , default_fingerprint2 , sizeof ( default_fingerprint2 ) ) ;
Settings - > tele_period = TELE_PERIOD ;
Settings - > mqttlog_level = MQTT_LOG_LEVEL ;
Settings - > mqtt_keepalive = MQTT_KEEPALIVE ;
Settings - > mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT ;
2021-06-15 09:15:36 +01:00
Settings - > mqtt_wifi_timeout = MQTT_WIFI_CLIENT_TIMEOUT / 100 ;
2017-10-18 17:22:34 +01:00
2018-06-02 15:59:09 +01:00
// Energy
2020-05-06 18:21:04 +01:00
flag . no_power_on_check | = ENERGY_VOLTAGE_ALWAYS ;
flag2 . current_resolution | = 3 ;
// flag2.voltage_resolution |= 0;
// flag2.wattage_resolution |= 0;
flag2 . energy_resolution | = ENERGY_RESOLUTION ;
flag3 . dds2382_model | = ENERGY_DDS2382_MODE ;
flag3 . hardware_energy_total | = ENERGY_HARDWARE_TOTALS ;
2021-06-11 17:14:12 +01:00
Settings - > param [ P_MAX_POWER_RETRY ] = MAX_POWER_RETRY ;
// Settings->energy_power_delta[0] = 0;
// Settings->energy_power_delta[1] = 0;
// Settings->energy_power_delta[2] = 0;
Settings - > energy_power_calibration = HLW_PREF_PULSE ;
Settings - > energy_voltage_calibration = HLW_UREF_PULSE ;
Settings - > energy_current_calibration = HLW_IREF_PULSE ;
2022-08-05 14:25:39 +01:00
// Settings->energy_kWhtoday_ph[0] = 0;
// Settings->energy_kWhtoday_ph[1] = 0;
// Settings->energy_kWhtoday_ph[2] = 0;
// Settings->energy_kWhyesterday_ph[0] = 0;
// Settings->energy_kWhyesterday_ph[1] = 0;
// Settings->energy_kWhyesterday_ph[2] = 0;
2021-06-11 17:14:12 +01:00
// Settings->energy_kWhdoy = 0;
// Settings->energy_min_power = 0;
// Settings->energy_max_power = 0;
// Settings->energy_min_voltage = 0;
// Settings->energy_max_voltage = 0;
// Settings->energy_min_current = 0;
// Settings->energy_max_current = 0;
// Settings->energy_max_power_limit = 0; // MaxPowerLimit
Settings - > energy_max_power_limit_hold = MAX_POWER_HOLD ;
Settings - > energy_max_power_limit_window = MAX_POWER_WINDOW ;
// Settings->energy_max_power_safe_limit = 0; // MaxSafePowerLimit
Settings - > energy_max_power_safe_limit_hold = SAFE_POWER_HOLD ;
Settings - > energy_max_power_safe_limit_window = SAFE_POWER_WINDOW ;
// Settings->energy_max_energy = 0; // MaxEnergy
// Settings->energy_max_energy_start = 0; // MaxEnergyStart
2022-08-05 14:25:39 +01:00
// Settings->energy_kWhtotal_ph[0] = 0;
// Settings->energy_kWhtotal_ph[1] = 0;
// Settings->energy_kWhtotal_ph[2] = 0;
RtcSettings . energy_kWhtotal_ph [ 0 ] = 0 ;
RtcSettings . energy_kWhtotal_ph [ 1 ] = 0 ;
RtcSettings . energy_kWhtotal_ph [ 2 ] = 0 ;
2021-06-11 17:14:12 +01:00
// memset((char*)&Settings->energy_usage, 0x00, sizeof(Settings->energy_usage));
2019-08-25 13:58:45 +01:00
memset ( ( char * ) & RtcSettings . energy_usage , 0x00 , sizeof ( RtcSettings . energy_usage ) ) ;
2021-06-11 17:14:12 +01:00
Settings - > param [ P_OVER_TEMP ] = ENERGY_OVERTEMP ;
2017-05-08 12:21:45 +01:00
2019-05-27 10:56:14 +01:00
// IRRemote
2020-05-06 18:21:04 +01:00
flag . ir_receive_decimal | = IR_DATA_RADIX ;
flag3 . receive_raw | = IR_ADD_RAW_DATA ;
2021-06-11 17:14:12 +01:00
Settings - > param [ P_IR_UNKNOW_THRESHOLD ] = IR_RCV_MIN_UNKNOWN_SIZE ;
2022-01-21 15:24:32 +00:00
Settings - > param [ P_IR_TOLERANCE ] = IR_RCV_TOLERANCE ;
2019-05-27 10:56:14 +01:00
2018-06-02 15:59:09 +01:00
// RF Bridge
2020-05-06 18:21:04 +01:00
flag . rf_receive_decimal | = RF_DATA_RADIX ;
2021-06-11 17:14:12 +01:00
// for (uint32_t i = 0; i < 17; i++) { Settings->rf_code[i][0] = 0; }
memcpy_P ( Settings - > rf_code [ 0 ] , kDefaultRfCode , 9 ) ;
2017-09-02 13:37:02 +01:00
2018-06-02 15:59:09 +01:00
// Domoticz
2021-06-11 17:14:12 +01:00
Settings - > domoticz_update_timer = DOMOTICZ_UPDATE_TIMER ;
2019-06-30 15:44:36 +01:00
// for (uint32_t i = 0; i < MAX_DOMOTICZ_IDX; i++) {
2021-06-11 17:14:12 +01:00
// Settings->domoticz_relay_idx[i] = 0;
// Settings->domoticz_key_idx[i] = 0;
// Settings->domoticz_switch_idx[i] = 0;
2018-06-02 15:59:09 +01:00
// }
2019-06-30 15:44:36 +01:00
// for (uint32_t i = 0; i < MAX_DOMOTICZ_SNS_IDX; i++) {
2021-06-11 17:14:12 +01:00
// Settings->domoticz_sensor_idx[i] = 0;
2018-06-02 15:59:09 +01:00
// }
2017-10-23 11:18:15 +01:00
2018-06-02 15:59:09 +01:00
// Sensor
2020-05-06 18:21:04 +01:00
flag . temperature_conversion | = TEMP_CONVERSION ;
flag . pressure_conversion | = PRESSURE_CONVERSION ;
flag2 . pressure_resolution | = PRESSURE_RESOLUTION ;
flag2 . humidity_resolution | = HUMIDITY_RESOLUTION ;
flag2 . temperature_resolution | = TEMP_RESOLUTION ;
flag3 . ds18x20_internal_pullup | = DS18X20_PULL_UP ;
flag3 . counter_reset_on_tele | = COUNTER_RESET ;
2021-06-11 17:14:12 +01:00
// Settings->altitude = 0;
2017-11-11 11:33:30 +00:00
2018-06-02 15:59:09 +01:00
// Rules
2021-06-11 17:14:12 +01:00
// Settings->rule_enabled = 0;
// Settings->rule_once = 0;
// for (uint32_t i = 1; i < MAX_RULE_SETS; i++) { Settings->rules[i][0] = '\0'; }
2020-05-06 18:21:04 +01:00
flag2 . calc_resolution | = CALC_RESOLUTION ;
2017-03-12 17:36:33 +00:00
2020-01-21 11:36:44 +00:00
// Timer
2020-05-06 18:21:04 +01:00
flag3 . timers_enable | = TIMERS_ENABLED ;
2020-01-21 11:36:44 +00:00
2018-06-02 15:59:09 +01:00
// Home Assistant
2020-05-06 18:21:04 +01:00
flag . hass_light | = HASS_AS_LIGHT ;
flag . hass_discovery | = HOME_ASSISTANT_DISCOVERY_ENABLE ;
flag3 . hass_tele_on_power | = TELE_ON_POWER ;
2017-02-19 16:49:17 +00:00
2018-06-02 15:59:09 +01:00
// Knx
2020-05-06 18:21:04 +01:00
flag . knx_enabled | = KNX_ENABLED ;
flag . knx_enable_enhancement | = KNX_ENHANCED ;
2017-03-12 17:36:33 +00:00
2018-06-02 15:59:09 +01:00
// Light
2020-05-06 18:21:04 +01:00
flag . pwm_control | = LIGHT_MODE ;
flag . ws_clock_reverse | = LIGHT_CLOCK_DIRECTION ;
flag . light_signal | = LIGHT_PAIRS_CO2 ;
flag . not_power_linked | = LIGHT_POWER_CONTROL ;
flag . decimal_text | = LIGHT_COLOR_RADIX ;
flag3 . pwm_multi_channels | = LIGHT_CHANNEL_MODE ;
flag3 . slider_dimmer_stay_on | = LIGHT_SLIDER_POWER ;
flag4 . alexa_ct_range | = LIGHT_ALEXA_CT_RANGE ;
flag4 . pwm_ct_mode | = LIGHT_PWM_CT_MODE ;
2020-08-30 14:44:28 +01:00
flag4 . white_blend_mode | = LIGHT_WHITE_BLEND_MODE ;
flag4 . virtual_ct | = LIGHT_VIRTUAL_CT ;
flag4 . virtual_ct_cw | = LIGHT_VIRTUAL_CT_CW ;
2020-01-20 17:49:57 +00:00
2021-06-11 17:14:12 +01:00
Settings - > pwm_frequency = PWM_FREQ ;
Settings - > pwm_range = PWM_RANGE ;
2022-01-27 20:30:05 +00:00
for ( uint32_t i = 0 ; i < LST_MAX ; i + + ) {
2021-06-11 17:14:12 +01:00
Settings - > light_color [ i ] = DEFAULT_LIGHT_COMPONENT ;
// Settings->pwm_value[i] = 0;
2017-04-25 17:24:42 +01:00
}
2021-06-11 17:14:12 +01:00
Settings - > light_correction = 1 ;
Settings - > light_dimmer = DEFAULT_LIGHT_DIMMER ;
// Settings->light_fade = 0;
Settings - > light_speed = 1 ;
// Settings->light_scheme = 0;
Settings - > light_width = 1 ;
// Settings->light_wakeup = 0;
Settings - > light_pixels = WS2812_LEDS ;
// Settings->light_rotation = 0;
Settings - > ws_width [ WS_SECOND ] = 1 ;
Settings - > ws_color [ WS_SECOND ] [ WS_RED ] = 255 ;
// Settings->ws_color[WS_SECOND][WS_GREEN] = 0;
Settings - > ws_color [ WS_SECOND ] [ WS_BLUE ] = 255 ;
Settings - > ws_width [ WS_MINUTE ] = 3 ;
// Settings->ws_color[WS_MINUTE][WS_RED] = 0;
Settings - > ws_color [ WS_MINUTE ] [ WS_GREEN ] = 255 ;
// Settings->ws_color[WS_MINUTE][WS_BLUE] = 0;
Settings - > ws_width [ WS_HOUR ] = 5 ;
Settings - > ws_color [ WS_HOUR ] [ WS_RED ] = 255 ;
// Settings->ws_color[WS_HOUR][WS_GREEN] = 0;
// Settings->ws_color[WS_HOUR][WS_BLUE] = 0;
Settings - > dimmer_hw_max = DEFAULT_DIMMER_MAX ;
Settings - > dimmer_hw_min = DEFAULT_DIMMER_MIN ;
Settings - > dimmer_step = DEFAULT_DIMMER_STEP ;
2020-10-30 13:49:36 +00:00
2021-03-09 19:41:14 +00:00
// Device Groups
2021-06-11 17:14:12 +01:00
* ( uint32_t * ) & Settings - > device_group_tie = 0x04030201 ;
2021-03-09 19:41:14 +00:00
2018-06-02 15:59:09 +01:00
// Display
2021-06-11 17:14:12 +01:00
// Settings->display_model = 0;
Settings - > display_mode = 1 ;
Settings - > display_refresh = 2 ;
Settings - > display_rows = 2 ;
Settings - > display_cols [ 0 ] = 16 ;
Settings - > display_cols [ 1 ] = 8 ;
2021-09-14 21:40:26 +01:00
Settings - > display_dimmer_protected = - 10 ; // 10%
2021-06-11 17:14:12 +01:00
Settings - > display_size = 1 ;
Settings - > display_font = 1 ;
// Settings->display_rotate = 0;
Settings - > display_address [ 0 ] = MTX_ADDRESS1 ;
Settings - > display_address [ 1 ] = MTX_ADDRESS2 ;
Settings - > display_address [ 2 ] = MTX_ADDRESS3 ;
Settings - > display_address [ 3 ] = MTX_ADDRESS4 ;
Settings - > display_address [ 4 ] = MTX_ADDRESS5 ;
Settings - > display_address [ 5 ] = MTX_ADDRESS6 ;
Settings - > display_address [ 6 ] = MTX_ADDRESS7 ;
Settings - > display_address [ 7 ] = MTX_ADDRESS8 ;
2018-06-02 15:59:09 +01:00
// Time
2018-11-01 12:00:05 +00:00
if ( ( ( APP_TIMEZONE > - 14 ) & & ( APP_TIMEZONE < 15 ) ) | | ( 99 = = APP_TIMEZONE ) ) {
2021-06-11 17:14:12 +01:00
Settings - > timezone = APP_TIMEZONE ;
Settings - > timezone_minutes = 0 ;
2018-11-01 12:00:05 +00:00
} else {
2021-06-11 17:14:12 +01:00
Settings - > timezone = APP_TIMEZONE / 60 ;
Settings - > timezone_minutes = abs ( APP_TIMEZONE % 60 ) ;
2018-11-01 12:00:05 +00:00
}
2020-05-04 19:00:05 +01:00
SettingsUpdateText ( SET_NTPSERVER1 , PSTR ( NTP_SERVER1 ) ) ;
SettingsUpdateText ( SET_NTPSERVER2 , PSTR ( NTP_SERVER2 ) ) ;
SettingsUpdateText ( SET_NTPSERVER3 , PSTR ( NTP_SERVER3 ) ) ;
2020-01-12 12:10:21 +00:00
for ( uint32_t i = 0 ; i < MAX_NTP_SERVERS ; i + + ) {
2019-12-16 14:13:57 +00:00
SettingsUpdateText ( SET_NTPSERVER1 + i , ReplaceCommaWithDot ( SettingsText ( SET_NTPSERVER1 + i ) ) ) ;
2017-04-25 17:24:42 +01:00
}
2021-06-11 17:14:12 +01:00
Settings - > latitude = ( int ) ( ( double ) LATITUDE * 1000000 ) ;
Settings - > longitude = ( int ) ( ( double ) LONGITUDE * 1000000 ) ;
2019-10-30 09:57:14 +00:00
SettingsResetStd ( ) ;
SettingsResetDst ( ) ;
2018-08-27 11:01:20 +01:00
2021-06-11 17:14:12 +01:00
Settings - > button_debounce = KEY_DEBOUNCE_TIME ;
Settings - > switch_debounce = SWITCH_DEBOUNCE_TIME ;
2018-09-29 15:55:53 +01:00
2019-06-30 15:44:36 +01:00
for ( uint32_t j = 0 ; j < 5 ; j + + ) {
2021-06-11 17:14:12 +01:00
Settings - > rgbwwTable [ j ] = 255 ;
2018-09-29 15:55:53 +01:00
}
2018-11-06 16:33:51 +00:00
2021-06-11 17:14:12 +01:00
Settings - > novasds_startingoffset = STARTING_OFFSET ;
2019-03-28 11:06:48 +00:00
2019-04-09 12:56:19 +01:00
SettingsDefaultWebColor ( ) ;
2021-07-14 13:20:50 +01:00
memset ( & Settings - > sensors , 0xFF , 32 ) ; // Enable all possible sensors
2019-11-03 16:54:39 +00:00
SettingsEnableAllI2cDrivers ( ) ;
2020-01-20 17:49:57 +00:00
// Tuya
2020-05-06 18:21:04 +01:00
flag3 . tuya_apply_o20 | = TUYA_SETOPTION_20 ;
2021-11-29 18:27:09 +00:00
flag5 . tuya_allow_dimmer_0 | = TUYA_ALLOW_DIMMER_0 ;
2022-04-01 16:33:57 +01:00
flag5 . tuya_exclude_from_mqtt | = TUYA_SETOPTION_137 ;
2020-05-06 18:21:04 +01:00
flag3 . tuya_serial_mqtt_publish | = MQTT_TUYA_RECEIVED ;
2021-04-19 11:25:53 +01:00
mbflag2 . temperature_set_res | = TUYA_TEMP_SET_RES ;
2020-05-06 18:21:04 +01:00
flag3 . buzzer_enable | = BUZZER_ENABLE ;
flag3 . shutter_mode | = SHUTTER_SUPPORT ;
flag3 . pcf8574_ports_inverted | = PCF8574_INVERT_PORTS ;
flag4 . zigbee_use_names | = ZIGBEE_FRIENDLY_NAMES ;
2021-03-02 21:47:40 +00:00
flag4 . zigbee_distinct_topics | = ZIGBEE_DISTINCT_TOPICS ;
2020-08-30 14:44:28 +01:00
flag4 . remove_zbreceived | = ZIGBEE_RMV_ZBRECEIVED ;
flag4 . zb_index_ep | = ZIGBEE_INDEX_EP ;
2022-09-19 15:19:43 +01:00
flag4 . zb_topic_fname | = ZIGBEE_TOPIC_FNAME ;
2020-08-30 14:44:28 +01:00
flag4 . mqtt_tls | = MQTT_TLS_ENABLED ;
flag4 . mqtt_no_retain | = MQTT_NO_RETAIN ;
2020-05-06 18:21:04 +01:00
2021-12-04 14:39:00 +00:00
flag5 . shift595_invert_outputs | = SHIFT595_INVERT_OUTPUTS ;
2021-12-10 20:53:43 +00:00
Settings - > shift595_device_count = SHIFT595_DEVICE_COUNT ;
flag5 . tls_use_fingerprint | = MQTT_TLS_FINGERPRINT ;
2022-04-16 18:43:08 +01:00
# ifdef BLE_ESP32_ENABLE
flag5 . mi32_enable | = BLE_ESP32_ENABLE ;
# endif
2021-12-04 14:39:00 +00:00
2021-06-11 17:14:12 +01:00
Settings - > flag = flag ;
Settings - > flag2 = flag2 ;
Settings - > flag3 = flag3 ;
Settings - > flag4 = flag4 ;
Settings - > flag5 = flag5 ;
2022-09-22 19:57:02 +01:00
Settings - > flag6 = flag6 ;
2021-05-09 12:09:53 +01:00
}
2021-04-25 16:22:38 +01:00
2021-05-09 12:09:53 +01:00
void SettingsDefaultSet3 ( void ) {
2021-04-25 16:22:38 +01:00
# ifdef USER_TEMPLATE
String user_template = USER_TEMPLATE ;
JsonTemplate ( ( char * ) user_template . c_str ( ) ) ;
2021-05-02 16:57:03 +01:00
user_template = ( const char * ) nullptr ; // Force deallocation of the String internal memory
# endif
# ifdef USE_RULES
# ifdef USER_RULE1
String user_rule1 = F ( " Rule1 " ) ;
user_rule1 + = USER_RULE1 ;
ExecuteCommand ( ( char * ) user_rule1 . c_str ( ) , SRC_RESTART ) ;
user_rule1 = ( const char * ) nullptr ; // Force deallocation of the String internal memory
# endif
# ifdef USER_RULE2
String user_rule2 = F ( " Rule2 " ) ;
user_rule2 + = USER_RULE2 ;
ExecuteCommand ( ( char * ) user_rule2 . c_str ( ) , SRC_RESTART ) ;
user_rule2 = ( const char * ) nullptr ; // Force deallocation of the String internal memory
# endif
# ifdef USER_RULE3
String user_rule3 = F ( " Rule3 " ) ;
user_rule3 + = USER_RULE3 ;
ExecuteCommand ( ( char * ) user_rule3 . c_str ( ) , SRC_RESTART ) ;
user_rule3 = ( const char * ) nullptr ; // Force deallocation of the String internal memory
# endif
# endif // USE_RULES
# ifdef USER_BACKLOG
String user_backlog = F ( " Backlog0 " ) ;
user_backlog + = USER_BACKLOG ;
ExecuteCommand ( ( char * ) user_backlog . c_str ( ) , SRC_RESTART ) ;
user_backlog = ( const char * ) nullptr ; // Force deallocation of the String internal memory
2021-04-25 16:22:38 +01:00
# endif
2017-02-19 16:49:17 +00:00
}
2018-06-02 15:59:09 +01:00
/********************************************************************************************/
2017-02-19 16:49:17 +00:00
2021-01-22 10:54:15 +00:00
void SettingsResetStd ( void ) {
2021-06-11 17:14:12 +01:00
Settings - > tflag [ 0 ] . hemis = TIME_STD_HEMISPHERE ;
Settings - > tflag [ 0 ] . week = TIME_STD_WEEK ;
Settings - > tflag [ 0 ] . dow = TIME_STD_DAY ;
Settings - > tflag [ 0 ] . month = TIME_STD_MONTH ;
Settings - > tflag [ 0 ] . hour = TIME_STD_HOUR ;
Settings - > toffset [ 0 ] = TIME_STD_OFFSET ;
2018-05-14 22:22:29 +01:00
}
2021-01-22 10:54:15 +00:00
void SettingsResetDst ( void ) {
2021-06-11 17:14:12 +01:00
Settings - > tflag [ 1 ] . hemis = TIME_DST_HEMISPHERE ;
Settings - > tflag [ 1 ] . week = TIME_DST_WEEK ;
Settings - > tflag [ 1 ] . dow = TIME_DST_DAY ;
Settings - > tflag [ 1 ] . month = TIME_DST_MONTH ;
Settings - > tflag [ 1 ] . hour = TIME_DST_HOUR ;
Settings - > toffset [ 1 ] = TIME_DST_OFFSET ;
2018-05-14 22:22:29 +01:00
}
2021-01-22 10:54:15 +00:00
void SettingsDefaultWebColor ( void ) {
2019-04-09 12:56:19 +01:00
char scolor [ 10 ] ;
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < COL_LAST ; i + + ) {
2019-04-09 12:56:19 +01:00
WebHexCode ( i , GetTextIndexed ( scolor , sizeof ( scolor ) , i , kWebColors ) ) ;
}
}
2021-01-22 10:54:15 +00:00
void SettingsEnableAllI2cDrivers ( void ) {
2021-06-11 17:14:12 +01:00
Settings - > i2c_drivers [ 0 ] = I2CDRIVERS_0_31 ;
Settings - > i2c_drivers [ 1 ] = I2CDRIVERS_32_63 ;
Settings - > i2c_drivers [ 2 ] = I2CDRIVERS_64_95 ;
2019-11-03 16:54:39 +00:00
}
2017-02-19 16:49:17 +00:00
/********************************************************************************************/
2021-01-22 10:54:15 +00:00
void SettingsDelta ( void ) {
2021-06-11 17:14:12 +01:00
if ( Settings - > version ! = VERSION ) { // Fix version dependent changes
2020-04-10 17:24:08 +01:00
# ifdef ESP8266
2021-02-05 14:50:24 +00:00
# ifndef UPGRADE_V8_MIN
// Although no direct upgrade is supported try to make a viable environment
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08000000 ) {
2020-12-02 10:59:01 +00:00
// Save SSIDs and Passwords
2021-06-11 17:14:12 +01:00
char temp31 [ strlen ( Settings - > ex_sta_ssid [ 0 ] ) + 1 ] ;
strncpy ( temp31 , Settings - > ex_sta_ssid [ 0 ] , sizeof ( temp31 ) ) ;
char temp32 [ strlen ( Settings - > ex_sta_ssid [ 1 ] ) + 1 ] ;
strncpy ( temp32 , Settings - > ex_sta_ssid [ 1 ] , sizeof ( temp32 ) ) ;
char temp41 [ strlen ( Settings - > ex_sta_pwd [ 0 ] ) + 1 ] ;
strncpy ( temp41 , Settings - > ex_sta_pwd [ 0 ] , sizeof ( temp41 ) ) ;
char temp42 [ strlen ( Settings - > ex_sta_pwd [ 1 ] ) + 1 ] ;
strncpy ( temp42 , Settings - > ex_sta_pwd [ 1 ] , sizeof ( temp42 ) ) ;
char temp7 [ strlen ( Settings - > ex_mqtt_host ) + 1 ] ;
strncpy ( temp7 , Settings - > ex_mqtt_host , sizeof ( temp7 ) ) ;
char temp9 [ strlen ( Settings - > ex_mqtt_user ) + 1 ] ;
strncpy ( temp9 , Settings - > ex_mqtt_user , sizeof ( temp9 ) ) ;
char temp10 [ strlen ( Settings - > ex_mqtt_pwd ) + 1 ] ;
strncpy ( temp10 , Settings - > ex_mqtt_pwd , sizeof ( temp10 ) ) ;
char temp11 [ strlen ( Settings - > ex_mqtt_topic ) + 1 ] ;
strncpy ( temp11 , Settings - > ex_mqtt_topic , sizeof ( temp11 ) ) ;
2020-12-02 10:59:01 +00:00
2020-12-01 07:48:06 +00:00
SettingsDefault ( ) ;
2020-12-02 10:59:01 +00:00
// Restore current SSIDs and Passwords
SettingsUpdateText ( SET_STASSID1 , temp31 ) ;
SettingsUpdateText ( SET_STASSID2 , temp32 ) ;
SettingsUpdateText ( SET_STAPWD1 , temp41 ) ;
SettingsUpdateText ( SET_STAPWD2 , temp42 ) ;
# if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
2021-06-11 17:14:12 +01:00
if ( ! strlen ( Settings - > ex_mqtt_user ) ) {
2020-12-02 10:59:01 +00:00
SettingsUpdateText ( SET_MQTT_HOST , temp7 ) ;
SettingsUpdateText ( SET_MQTT_USER , temp9 ) ;
} else {
char aws_mqtt_host [ 66 ] ;
snprintf_P ( aws_mqtt_host , sizeof ( aws_mqtt_host ) , PSTR ( " %s%s " ) , temp9 , temp7 ) ;
SettingsUpdateText ( SET_MQTT_HOST , aws_mqtt_host ) ;
SettingsUpdateText ( SET_MQTT_USER , " " ) ;
}
# else // No USE_MQTT_TLS and USE_MQTT_AWS_IOT
SettingsUpdateText ( SET_MQTT_HOST , temp7 ) ;
SettingsUpdateText ( SET_MQTT_USER , temp9 ) ;
# endif // USE_MQTT_TLS and USE_MQTT_AWS_IOT
SettingsUpdateText ( SET_MQTT_PWD , temp10 ) ;
SettingsUpdateText ( SET_MQTT_TOPIC , temp11 ) ;
2020-12-01 07:48:06 +00:00
}
2021-02-05 14:50:24 +00:00
# endif // UPGRADE_V8_MIN
2021-02-05 14:21:06 +00:00
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08020003 ) {
SettingsUpdateText ( SET_TEMPLATE_NAME , Settings - > user_template_name ) ;
Settings - > zb_channel = 0 ; // set channel to zero to force reinit of zigbee parameters
2020-03-29 16:41:31 +01:00
}
2020-04-10 17:24:08 +01:00
# endif // ESP8266
2019-12-16 14:13:57 +00:00
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08020004 ) {
Settings - > flag3 . mqtt_buttons = 0 ; // SetOption73 (0) - Decouple button from relay and send just mqtt topic
2020-04-17 10:57:09 +01:00
# ifdef ESP8266
2021-06-11 17:14:12 +01:00
Settings - > config_version = 0 ; // ESP8266 (Has been 0 for long time)
2020-04-17 10:57:09 +01:00
# endif // ESP8266
# ifdef ESP32
2022-02-08 15:30:10 +00:00
# ifdef CONFIG_IDF_TARGET_ESP32S3
Settings - > config_version = 2 ; // ESP32S3
2022-02-08 18:05:54 +00:00
# elif CONFIG_IDF_TARGET_ESP32S2
Settings - > config_version = 3 ; // ESP32S2
# elif CONFIG_IDF_TARGET_ESP32C3
Settings - > config_version = 4 ; // ESP32C3
2022-02-03 11:33:55 +00:00
# else
2021-06-11 17:14:12 +01:00
Settings - > config_version = 1 ; // ESP32
2022-02-08 15:30:10 +00:00
# endif // CONFIG_IDF_TARGET_ESP32S3
2020-04-17 10:57:09 +01:00
# endif // ESP32
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08020006 ) {
2020-05-01 16:30:09 +01:00
# ifdef ESP32
2021-06-11 17:14:12 +01:00
Settings - > module = WEMOS ;
2020-05-01 16:30:09 +01:00
ModuleDefault ( WEMOS ) ;
# endif // ESP32
2020-05-08 18:33:20 +01:00
// make sure the empty rules have two consecutive NULLs, to be compatible with compressed rules
2021-06-11 17:14:12 +01:00
if ( Settings - > rules [ 0 ] [ 0 ] = = 0 ) { Settings - > rules [ 0 ] [ 1 ] = 0 ; }
if ( Settings - > rules [ 1 ] [ 0 ] = = 0 ) { Settings - > rules [ 1 ] [ 1 ] = 0 ; }
if ( Settings - > rules [ 2 ] [ 0 ] = = 0 ) { Settings - > rules [ 2 ] [ 1 ] = 0 ; }
2020-05-01 16:30:09 +01:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08030002 ) {
2020-05-23 12:04:17 +01:00
SettingsUpdateText ( SET_DEVICENAME , SettingsText ( SET_FRIENDLYNAME1 ) ) ;
2021-06-11 17:14:12 +01:00
Settings - > ledpwm_off = 0 ;
Settings - > ledpwm_on = 255 ;
Settings - > ledpwm_mask = 0 ;
2020-05-20 03:38:24 +01:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08030104 ) {
Settings - > flag4 . network_wifi = 1 ;
Settings - > flag4 . network_ethernet = 1 ;
2020-06-15 17:27:04 +01:00
}
2020-06-16 17:36:49 +01:00
# ifdef ESP32
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08030105 ) {
Settings - > eth_type = ETH_TYPE ;
Settings - > eth_clk_mode = ETH_CLKMODE ;
Settings - > eth_address = ETH_ADDRESS ;
2020-06-17 13:06:46 +01:00
}
2020-10-11 10:31:46 +01:00
# endif // ESP32
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08030106 ) {
Settings - > fallback_module = FALLBACK_MODULE ;
2020-06-16 17:36:49 +01:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x08040003 ) {
Settings - > energy_power_delta [ 0 ] = Settings - > hass_new_discovery ; // replaced ex2_energy_power_delta on 8.5.0.1
Settings - > energy_power_delta [ 1 ] = 0 ;
Settings - > energy_power_delta [ 2 ] = 0 ;
2020-08-23 17:29:16 +01:00
}
2020-10-11 10:31:46 +01:00
# ifdef ESP8266
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09000002 ) {
2020-10-11 10:31:46 +01:00
char parameters [ 32 ] ;
snprintf_P ( parameters , sizeof ( parameters ) , PSTR ( " %d,%d,%d,%d,%d " ) ,
2021-08-11 17:43:11 +01:00
Settings - > influxdb_version , Settings - > sensors [ 0 ] [ 0 ] , Settings - > sensors [ 0 ] [ 1 ] , ( int ) Settings - > sensors [ 0 ] [ 2 ] , Settings - > mbflag2 . data ) ;
2020-10-11 10:31:46 +01:00
SettingsUpdateText ( SET_ADC_PARAM1 , parameters ) ;
}
# endif // ESP8266
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09010000 ) {
Settings - > dimmer_step = DEFAULT_DIMMER_STEP ;
2020-11-07 10:09:16 +00:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09020003 ) {
Settings - > flag3 . use_wifi_rescan = true ; // As a result of #10395
2021-01-05 16:14:01 +00:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09020006 ) {
2021-02-05 15:36:25 +00:00
for ( uint32_t i = 0 ; i < MAX_SWITCHES_SET ; i + + ) {
2021-06-11 17:14:12 +01:00
Settings - > switchmode [ i ] = ( i < 8 ) ? Settings - > ex_switchmode [ i ] : SWITCH_MODE ;
2021-02-05 10:58:24 +00:00
}
2021-02-05 15:36:25 +00:00
for ( uint32_t i = 0 ; i < MAX_INTERLOCKS_SET ; i + + ) {
2022-03-17 15:03:40 +00:00
Settings - > interlock [ i ] = ( i < 4 ) ? Settings - > ds3502_state [ i ] : 0 ;
2021-02-05 14:21:06 +00:00
}
2021-02-05 10:58:24 +00:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09020007 ) {
* ( uint32_t * ) & Settings - > device_group_tie = 0x04030201 ;
2021-02-09 21:10:32 +00:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09030102 ) {
Settings - > mqtt_keepalive = MQTT_KEEPALIVE ;
Settings - > mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT ;
2021-03-18 16:44:10 +00:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09030104 ) {
Settings - > mbflag2 . data = 0 ;
2021-04-19 11:25:53 +01:00
}
2021-06-11 17:14:12 +01:00
if ( Settings - > version < 0x09040002 ) {
Settings - > sbflag1 . data = 0 ;
2021-04-30 14:42:57 +01:00
}
2021-06-15 09:15:36 +01:00
if ( Settings - > version < 0x09040006 ) {
Settings - > mqtt_wifi_timeout = MQTT_WIFI_CLIENT_TIMEOUT / 100 ;
}
2021-07-01 14:19:35 +01:00
# ifdef CONFIG_IDF_TARGET_ESP32C3
if ( Settings - > version < 0x09050002 ) {
if ( Settings - > cfg_size ! = sizeof ( TSettings ) ) {
// Fix onetime Settings layout due to changed ESP32-C3 myio and mytmplt types sizes
memmove_P ( ( uint8_t * ) & Settings - > user_template , ( uint8_t * ) & Settings - > free_esp32c3_3D8 , sizeof ( TSettings ) - 0x3FC ) ;
memmove_P ( ( uint8_t * ) & Settings - > eth_type , ( uint8_t * ) & Settings - > free_esp32c3_42A , sizeof ( TSettings ) - 0x446 ) ;
// Reset for future use
memset ( & Settings - > free_esp32c3_3D8 , 0x00 , sizeof ( Settings - > free_esp32c3_3D8 ) ) ;
memset ( & Settings - > free_esp32c3_42A , 0x00 , sizeof ( Settings - > free_esp32c3_42A ) ) ;
}
}
# endif
2021-07-14 13:20:50 +01:00
if ( Settings - > version < 0x09050003 ) {
memset ( & Settings - > sensors , 0xFF , 16 ) ; // Enable all possible sensors
}
2021-07-29 15:57:04 +01:00
if ( Settings - > version < 0x09050004 ) {
2022-08-05 14:25:39 +01:00
Settings - > ex_energy_kWhtotal = Settings - > ipv4_address [ 4 ] ;
2021-07-29 15:57:04 +01:00
ParseIPv4 ( & Settings - > ipv4_address [ 4 ] , PSTR ( WIFI_DNS2 ) ) ;
}
2021-08-01 16:51:54 +01:00
if ( Settings - > version < 0x09050005 ) {
2021-08-02 01:25:32 +01:00
Settings - > sbflag1 . range_extender = WIFI_RGX_STATE ;
Settings - > sbflag1 . range_extender_napt = WIFI_RGX_NAPT ;
2021-08-01 16:51:54 +01:00
ParseIPv4 ( & Settings - > ipv4_rgx_address , PSTR ( WIFI_RGX_IP_ADDRESS ) ) ;
ParseIPv4 ( & Settings - > ipv4_rgx_subnetmask , PSTR ( WIFI_RGX_SUBNETMASK ) ) ;
SettingsUpdateText ( SET_RGX_SSID , PSTR ( WIFI_RGX_SSID ) ) ;
SettingsUpdateText ( SET_RGX_PASSWORD , PSTR ( WIFI_RGX_PASSWORD ) ) ;
2022-05-08 16:33:11 +01:00
if ( ( 8883 = = Settings - > mqtt_port ) | | ( 8884 = = Settings - > mqtt_port ) | | ( 443 = = Settings - > mqtt_port ) ) {
// Turn on TLS for port 8883 (TLS), 8884 (TLS, client certificate), 443 (TLS, user/password)
Settings - > flag4 . mqtt_tls = true ;
}
2021-08-01 16:51:54 +01:00
}
2021-08-20 14:54:26 +01:00
if ( Settings - > version < 0x09050007 ) {
2021-09-01 01:25:06 +01:00
# ifdef DISABLE_REFERER_CHK
Settings - > flag5 . disable_referer_chk | = false ;
# else
Settings - > flag5 . disable_referer_chk | = true ;
# endif
2021-08-20 14:54:26 +01:00
}
2022-04-07 14:06:21 +01:00
if ( Settings - > version < 0x09050009 ) { // 9.5.0.9
2021-09-27 13:31:16 +01:00
memset ( & Settings - > energy_kWhtoday_ph , 0 , 36 ) ;
memset ( & RtcSettings . energy_kWhtoday_ph , 0 , 24 ) ;
2022-08-05 14:25:39 +01:00
Settings - > energy_kWhtotal_ph [ 0 ] = Settings - > ex_energy_kWhtotal ;
Settings - > energy_kWhtoday_ph [ 0 ] = Settings - > ex_energy_kWhtoday ;
Settings - > energy_kWhyesterday_ph [ 0 ] = Settings - > ex_energy_kWhyesterday ;
RtcSettings . energy_kWhtoday_ph [ 0 ] = RtcSettings . ex_energy_kWhtoday ;
RtcSettings . energy_kWhtotal_ph [ 0 ] = RtcSettings . ex_energy_kWhtotal ;
2021-09-27 13:31:16 +01:00
}
2022-04-07 14:06:21 +01:00
if ( Settings - > version < 0x0A000003 ) { // 10.0.0.3
2021-11-13 13:38:21 +00:00
if ( 0 = = Settings - > param [ P_ARP_GRATUITOUS ] ) {
Settings - > param [ P_ARP_GRATUITOUS ] = WIFI_ARP_INTERVAL ;
2021-12-01 20:38:28 +00:00
# ifdef USE_TLS
for ( uint32_t i = 0 ; i < 20 ; i + + ) {
if ( Settings - > mqtt_fingerprint [ 0 ] [ i ] ) {
Settings - > flag5 . tls_use_fingerprint = true ; // if the fingerprint1 is non null we expect it to be actually used
break ;
}
}
# endif
2021-11-13 13:38:21 +00:00
}
}
2022-04-07 14:06:21 +01:00
if ( Settings - > version < 0x0A010003 ) { // 10.1.0.3
2021-12-25 11:58:24 +00:00
Settings - > sserial_config = Settings - > serial_config ;
}
2022-04-07 14:06:21 +01:00
if ( Settings - > version < 0x0A010006 ) { // 10.1.0.6
2022-01-16 15:19:28 +00:00
Settings - > web_time_start = 0 ;
Settings - > web_time_end = 0 ;
}
2022-02-25 14:15:07 +00:00
if ( Settings - > version < 0x0B000003 ) { // 11.0.0.3
memcpy ( Settings - > pulse_timer , Settings - > ex_pulse_timer , 16 ) ;
}
2022-04-07 14:06:21 +01:00
if ( Settings - > version < 0x0B000006 ) { // 11.0.0.6
Settings - > weight_absconv_a = 0 ;
Settings - > weight_absconv_b = 0 ;
}
2022-04-09 17:24:37 +01:00
if ( Settings - > version < 0x0B000007 ) { // 11.0.0.7
Settings - > weight_user_tare = 0 ;
Settings - > weight_offset = 0 ;
# ifdef USE_HX711
Settings - > weight_offset = Settings - > energy_frequency_calibration * Settings - > weight_calibration ;
# endif
}
2022-06-19 16:57:43 +01:00
if ( Settings - > version < 0x0C000102 ) { // 12.0.1.2
Settings - > dns_timeout = DNS_TIMEOUT ;
}
2022-06-22 22:45:25 +01:00
if ( Settings - > version < 0x0C000202 ) { // 12.0.2.2
for ( uint32_t i = 0 ; i < 3 ; i + + ) {
Settings - > global_sensor_index [ i ] = 0 ;
}
}
2022-07-16 13:32:18 +01:00
if ( Settings - > version < 0x0C000204 ) { // 12.0.2.4
Settings - > param [ P_BISTABLE_PULSE ] = APP_BISTABLE_PULSE ;
}
2022-09-27 14:55:45 +01:00
# ifdef ESP32
2022-09-27 14:36:35 +01:00
if ( Settings - > version < 0x0C010103 ) { // 12.1.1.3
Settings - > touch_threshold = ESP32_TOUCH_THRESHOLD ;
}
2022-09-27 14:55:45 +01:00
# endif
2021-07-01 14:19:35 +01:00
2021-06-11 17:14:12 +01:00
Settings - > version = VERSION ;
2017-10-18 17:22:34 +01:00
SettingsSave ( 1 ) ;
2017-02-19 16:49:17 +00:00
}
2020-05-20 03:38:24 +01:00
2017-02-19 16:49:17 +00:00
}