From 49aba4ddf6424f1ac9e756059375a28b5e15343f Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 4 May 2022 18:56:16 +0200 Subject: [PATCH 1/5] Update xdrv_29_deepsleep.ino --- tasmota/xdrv_29_deepsleep.ino | 53 +++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index 284100b52..0fec046cf 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -37,6 +37,7 @@ #endif const uint32_t DEEPSLEEP_MAX = 10 * 366 * 24 * 60 * 60; // Allow max 10 years sleep +const uint32_t DEEPSLEEP_MAX_CYCLE = 60 * 60; // Maximum time for a deepsleep as defined by chip hardware const uint32_t DEEPSLEEP_MIN_TIME = 5; // Allow 5 seconds skew const uint32_t DEEPSLEEP_START_COUNTDOWN = 4; // Allow 4 seconds to update web console before deepsleep @@ -46,6 +47,7 @@ const char kDeepsleepCommands[] PROGMEM = D_PRFX_DEEPSLEEP "|" void (* const DeepsleepCommand[])(void) PROGMEM = { &CmndDeepsleepTime }; +uint32_t deepsleep_sleeptime = 0; uint8_t deepsleep_flag = 0; bool DeepSleepEnabled(void) @@ -59,9 +61,34 @@ bool DeepSleepEnabled(void) pinMode(Pin(GPIO_DEEPSLEEP), INPUT_PULLUP); return (digitalRead(Pin(GPIO_DEEPSLEEP))); // Disable DeepSleep if user holds pin GPIO_DEEPSLEEP low } + return true; // Enabled } +void DeepSleepReInit(void) +{ + if ((ResetReason() == REASON_DEEP_SLEEP_AWAKE) && DeepSleepEnabled()) { + if ((RtcSettings.ultradeepsleep > DEEPSLEEP_MAX_CYCLE) && (RtcSettings.ultradeepsleep < 1700000000)) { + // Go back to sleep after 60 minutes if requested deepsleep has not been reached + RtcSettings.ultradeepsleep = RtcSettings.ultradeepsleep - DEEPSLEEP_MAX_CYCLE; + AddLog(LOG_LEVEL_ERROR, PSTR("DSL: Remain DeepSleep %d"), RtcSettings.ultradeepsleep); + RtcSettingsSave(); + RtcRebootReset(); +#ifdef ESP8266 + ESP.deepSleep(100 * RtcSettings.deepsleep_slip * (DEEPSLEEP_MAX_CYCLE < RtcSettings.ultradeepsleep ? DEEPSLEEP_MAX_CYCLE : RtcSettings.ultradeepsleep), WAKE_RF_DEFAULT); +#endif // ESP8266 +#ifdef ESP32 + esp_sleep_enable_timer_wakeup(100 * RtcSettings.deepsleep_slip * (DEEPSLEEP_MAX_CYCLE < RtcSettings.ultradeepsleep ? DEEPSLEEP_MAX_CYCLE : RtcSettings.ultradeepsleep)); + esp_deep_sleep_start(); +#endif // ESP32 + yield(); + // Sleeping + } + } + // Stay awake + RtcSettings.ultradeepsleep = 0; +} + void DeepSleepPrepare(void) { // Deepsleep_slip is ideally 10.000 == 100% @@ -79,44 +106,49 @@ void DeepSleepPrepare(void) // Timeslip in 0.1 seconds between the real wakeup and the calculated wakeup // Because deepsleep is in second and timeslip in 0.1 sec the compare always check if the slip is in the 10% range - int32_t timeslip = ((int32_t)RtcSettings.nextwakeup + millis() / 1000 - (int32_t)LocalTime()) * 10; + int16_t timeslip = (int16_t)(RtcSettings.nextwakeup + millis() / 1000 - LocalTime()) * 10; // Allow 10% of deepsleep error to count as valid deepsleep; expecting 3-4% // if more then 10% timeslip = 0 == non valid wakeup; maybe manual timeslip = (timeslip < -(int32_t)Settings->deepsleep) ? 0 : (timeslip > (int32_t)Settings->deepsleep) ? 0 : 1; if (timeslip) { - RtcSettings.nextwakeup += Settings->deepsleep; - RtcSettings.deepsleep_slip = (RtcSettings.nextwakeup - LocalTime()) * RtcSettings.deepsleep_slip / tmax((Settings->deepsleep - (millis() / 1000)),5); + RtcSettings.deepsleep_slip = (Settings->deepsleep + RtcSettings.nextwakeup - LocalTime()) * RtcSettings.deepsleep_slip / tmax((Settings->deepsleep - (millis() / 1000)),5); // Avoid crazy numbers. Again maximum 10% deviation. RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000); - + RtcSettings.nextwakeup += Settings->deepsleep; } // It may happen that wakeup in just <5 seconds in future // In this case also add deepsleep to nextwakeup - if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) { + if (RtcSettings.nextwakeup <= (LocalTime() - DEEPSLEEP_MIN_TIME)) { // ensure nextwakeup is at least in the future RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep; } String dt = GetDT(RtcSettings.nextwakeup); // 2017-03-07T11:08:02 + // Limit sleeptime to DEEPSLEEP_MAX_CYCLE + // uint32_t deepsleep_sleeptime = DEEPSLEEP_MAX_CYCLE < (RtcSettings.nextwakeup - LocalTime()) ? (uint32_t)DEEPSLEEP_MAX_CYCLE : RtcSettings.nextwakeup - LocalTime(); + deepsleep_sleeptime = tmin((uint32_t)DEEPSLEEP_MAX_CYCLE ,RtcSettings.nextwakeup - LocalTime()); // stat/tasmota/DEEPSLEEP = {"DeepSleep":{"Time":"2019-11-12T21:33:45","Epoch":1573590825}} Response_P(PSTR("{\"" D_PRFX_DEEPSLEEP "\":{\"" D_JSON_TIME "\":\"%s\",\"Epoch\":%d}}"), (char*)dt.c_str(), RtcSettings.nextwakeup); MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_PRFX_DEEPSLEEP)); + +// Response_P(S_LWT_OFFLINE); +// MqttPublishPrefixTopicRulesProcess_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic } void DeepSleepStart(void) { WifiShutdown(); + RtcSettings.ultradeepsleep = RtcSettings.nextwakeup - LocalTime(); RtcSettingsSave(); RtcRebootReset(); - uint64_t deepsleepticker = 100 * (uint64_t)RtcSettings.deepsleep_slip * (uint64_t)(RtcSettings.nextwakeup>LocalTime()?RtcSettings.nextwakeup - LocalTime():RtcSettings.nextwakeup); #ifdef ESP8266 - ESP.deepSleep(deepsleepticker); + ESP.deepSleep(100 * RtcSettings.deepsleep_slip * deepsleep_sleeptime); #endif // ESP8266 #ifdef ESP32 - esp_sleep_enable_timer_wakeup(deepsleepticker); + esp_sleep_enable_timer_wakeup(100 * RtcSettings.deepsleep_slip * deepsleep_sleeptime); esp_deep_sleep_start(); #endif // ESP32 yield(); @@ -179,13 +211,16 @@ bool Xdrv29(uint8_t function) DeepSleepEverySecond(); break; case FUNC_AFTER_TELEPERIOD: - if (DeepSleepEnabled() && !deepsleep_flag && (Settings->tele_period == 10 || Settings->tele_period == 300 || millis() > 20000 )) { + if (DeepSleepEnabled() && !deepsleep_flag && (Settings->tele_period == 10 || Settings->tele_period == 300 || UpTime() > Settings->tele_period)) { deepsleep_flag = DEEPSLEEP_START_COUNTDOWN; // Start deepsleep in 4 seconds } break; case FUNC_COMMAND: result = DecodeCommand(kDeepsleepCommands, DeepsleepCommand); break; + case FUNC_PRE_INIT: + DeepSleepReInit(); + break; } return result; } From 0c43ef7b79cad77c50902c5cc9905365d97fe344 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 4 May 2022 19:00:25 +0200 Subject: [PATCH 2/5] Update xdrv_29_deepsleep.ino --- tasmota/xdrv_29_deepsleep.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index 0fec046cf..a5a402e90 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -211,7 +211,7 @@ bool Xdrv29(uint8_t function) DeepSleepEverySecond(); break; case FUNC_AFTER_TELEPERIOD: - if (DeepSleepEnabled() && !deepsleep_flag && (Settings->tele_period == 10 || Settings->tele_period == 300 || UpTime() > Settings->tele_period)) { + if (DeepSleepEnabled() && !deepsleep_flag && (Settings->tele_period == 10 || Settings->tele_period == 300 || millis() > 20000)) { deepsleep_flag = DEEPSLEEP_START_COUNTDOWN; // Start deepsleep in 4 seconds } break; From cdce233f43513a17991775e4e4450f0f1c50c98a Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 4 May 2022 19:04:43 +0200 Subject: [PATCH 3/5] Update xdrv_29_deepsleep.ino --- tasmota/xdrv_29_deepsleep.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index a5a402e90..dc7d76adc 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -120,7 +120,7 @@ void DeepSleepPrepare(void) // It may happen that wakeup in just <5 seconds in future // In this case also add deepsleep to nextwakeup - if (RtcSettings.nextwakeup <= (LocalTime() - DEEPSLEEP_MIN_TIME)) { + if (RtcSettings.nextwakeup <= (LocalTime() + DEEPSLEEP_MIN_TIME)) { // ensure nextwakeup is at least in the future RtcSettings.nextwakeup += (((LocalTime() + DEEPSLEEP_MIN_TIME - RtcSettings.nextwakeup) / Settings->deepsleep) + 1) * Settings->deepsleep; } From c022e353887348a087842d30984af7d7af776855 Mon Sep 17 00:00:00 2001 From: stefanbode Date: Wed, 4 May 2022 19:07:22 +0200 Subject: [PATCH 4/5] Update xdrv_29_deepsleep.ino --- tasmota/xdrv_29_deepsleep.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasmota/xdrv_29_deepsleep.ino b/tasmota/xdrv_29_deepsleep.ino index dc7d76adc..9cfa1f070 100644 --- a/tasmota/xdrv_29_deepsleep.ino +++ b/tasmota/xdrv_29_deepsleep.ino @@ -112,10 +112,10 @@ void DeepSleepPrepare(void) // if more then 10% timeslip = 0 == non valid wakeup; maybe manual timeslip = (timeslip < -(int32_t)Settings->deepsleep) ? 0 : (timeslip > (int32_t)Settings->deepsleep) ? 0 : 1; if (timeslip) { - RtcSettings.deepsleep_slip = (Settings->deepsleep + RtcSettings.nextwakeup - LocalTime()) * RtcSettings.deepsleep_slip / tmax((Settings->deepsleep - (millis() / 1000)),5); + RtcSettings.nextwakeup += Settings->deepsleep; + RtcSettings.deepsleep_slip = (RtcSettings.nextwakeup - LocalTime()) * RtcSettings.deepsleep_slip / tmax((Settings->deepsleep - (millis() / 1000)),5); // Avoid crazy numbers. Again maximum 10% deviation. RtcSettings.deepsleep_slip = tmin(tmax(RtcSettings.deepsleep_slip, 9000), 11000); - RtcSettings.nextwakeup += Settings->deepsleep; } // It may happen that wakeup in just <5 seconds in future From bc64dd6b9d8a011cdf9377e111ae635508dd5c2b Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Wed, 4 May 2022 20:26:29 +0200 Subject: [PATCH 5/5] Real Python fix ;-) Thx @Staars --- pio-tools/post_esp32.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pio-tools/post_esp32.py b/pio-tools/post_esp32.py index 782eed772..f0e670a72 100644 --- a/pio-tools/post_esp32.py +++ b/pio-tools/post_esp32.py @@ -36,13 +36,8 @@ FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32") variants_dir = join(FRAMEWORK_DIR, "variants", "tasmota") def esp32_fetch_safemode_bin(chip): - if "solo1" in env.subst("$BUILD_DIR"): - safemode_fw_url = "https://github.com/arendst/Tasmota-firmware/raw/main/firmware/tasmota32/tasmota32solo1-safemode.bin" - safemode_fw_name = join(variants_dir,"tasmota32solo1-safemode.bin") - else: - safemode_fw_url = "https://github.com/arendst/Tasmota-firmware/raw/main/firmware/tasmota32/tasmota" + chip[3:] + "-safemode.bin" - safemode_fw_name = join(variants_dir,"tasmota" + chip[3:] + "-safemode.bin") - + safemode_fw_url = "https://github.com/arendst/Tasmota-firmware/raw/main/firmware/tasmota32/tasmota" + chip[3:] + "-safemode.bin" + safemode_fw_name = join(variants_dir,"tasmota" + ("32solo1" if "solo1" in env.subst("$BUILD_DIR") else chip[3:]) + "-safemode.bin") if(exists(safemode_fw_name)): print("Safemode binary already in place.") return @@ -54,7 +49,7 @@ def esp32_fetch_safemode_bin(chip): def esp32_copy_new_safemode_bin(chip,new_local_safemode_fw): print("Copy new local safemode firmware to variants dir -> using it for further flashing operations") - safemode_fw_name = join(variants_dir,"tasmota" + chip[3:] + "-safemode.bin") + safemode_fw_name = join(variants_dir,"tasmota" + ("32solo1" if "solo1" in env.subst("$BUILD_DIR") else chip[3:]) + "-safemode.bin") if os.path.exists(variants_dir): shutil.copy(new_local_safemode_fw, safemode_fw_name)