Skip to content

Commit

Permalink
SLEEP_DURATION now allows for values up to 1 day! #127
Browse files Browse the repository at this point in the history
  • Loading branch information
lmarzen committed Sep 28, 2024
1 parent d804ce7 commit f37e9e1
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 45 deletions.
2 changes: 1 addition & 1 deletion platformio/include/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ extern const char *REFRESH_TIME_FORMAT;
extern const char *NTP_SERVER_1;
extern const char *NTP_SERVER_2;
extern const unsigned long NTP_TIMEOUT;
extern const long SLEEP_DURATION;
extern const int SLEEP_DURATION;
extern const int BED_TIME;
extern const int WAKE_TIME;
extern const int HOURLY_GRAPH_MAX;
Expand Down
16 changes: 13 additions & 3 deletions platformio/src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,24 @@ const char *NTP_SERVER_2 = "time.nist.gov";
// NTP_TIMEOUT or select closer/lower latency time servers.
const unsigned long NTP_TIMEOUT = 20000; // ms
// Sleep duration in minutes. (aka how often esp32 will wake for an update)
// Aligned to the nearest minute boundary and must evenly divide 60.
// Aligned to the nearest minute boundary.
// For example, if set to 30 (minutes) the display will update at 00 or 30
// minutes past the hour. (range: [2-60])
const long SLEEP_DURATION = 30;
// minutes past the hour. (range: [2-1440])
// Note: The OpenWeatherMap model is update every 10 minutes, so updating more
// frequently than that is unnessesary.
const int SLEEP_DURATION = 30; // minutes
// Bed Time Power Savings.
// If BED_TIME == WAKE_TIME, then this battery saving feature will be disabled.
// (range: [0-23])
const int BED_TIME = 00; // Last update at 00:00 (midnight) until WAKE_TIME.
const int WAKE_TIME = 06; // Hour of first update after BED_TIME, 06:00.
// Note that the minute alignment of SLEEP_DURATION begins at WAKE_TIME even if
// Bed Time Power Savings is disabled.
// For example, if WAKE_TIME = 00 (midnight) and SLEEP_DURATION = 120, then the
// display will update at 00:00, 02:00, 04:00... until BED_TIME.
// If you desire to have your display refresh exactly once a day, you should set
// SLEEP_DURATION = 1440, and you can set the time it should update each day by
// setting both BED_TIME and WAKE_TIME to the hour you want it to update.

// HOURLY OUTLOOK GRAPH
// Number of hours to display on the outlook graph. (range: [8-48])
Expand Down
79 changes: 38 additions & 41 deletions platformio/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,60 +46,57 @@ Preferences prefs;
/* Put esp32 into ultra low-power deep sleep (<11μA).
* Aligns wake time to the minute. Sleep times defined in config.cpp.
*/
void beginDeepSleep(unsigned long &startTime, tm *timeInfo)
void beginDeepSleep(unsigned long startTime, tm *timeInfo)
{
if (!getLocalTime(timeInfo))
{
Serial.println(TXT_REFERENCING_OLDER_TIME_NOTICE);
}

uint64_t sleepDuration = 0;
int extraHoursUntilWake = 0;
int curHour = timeInfo->tm_hour;

if (timeInfo->tm_min >= 58)
{ // if we are within 2 minutes of the next hour, then round up for the
// purposes of bed time
curHour = (curHour + 1) % 24;
extraHoursUntilWake += 1;
// To simplify sleep time calculations, the current time stored by timeInfo
// will be converted to time relative to the WAKE_TIME. This way if a
// SLEEP_DURATION is not a multiple of 60 minutes it can be more trivially,
// aligned and it can easily be deterimined whether we must sleep for
// additional time due to bedtime.
// i.e. when curHour == 0, then timeInfo->tm_hour == WAKE_TIME
int bedtimeHour = INT_MAX;
if (BED_TIME != WAKE_TIME) {
bedtimeHour = (BED_TIME - WAKE_TIME + 24) % 24;
}

if (BED_TIME < WAKE_TIME && curHour >= BED_TIME && curHour < WAKE_TIME)
{ // 0 B v W 24
// |--------------zzzzZzz---|
extraHoursUntilWake += WAKE_TIME - curHour;
}
else if (BED_TIME > WAKE_TIME && curHour < WAKE_TIME)
{ // 0 v W B 24
// |zZz----------------zzzzz|
extraHoursUntilWake += WAKE_TIME - curHour;
}
else if (BED_TIME > WAKE_TIME && curHour >= BED_TIME)
{ // 0 W B v 24
// |zzz----------------zzzZz|
extraHoursUntilWake += WAKE_TIME - (curHour - 24);
}
else // This feature is disabled (BED_TIME == WAKE_TIME)
{ // OR it is not past BED_TIME
extraHoursUntilWake = 0;
// time is relative to wake time
int curHour = (timeInfo->tm_hour - WAKE_TIME + 24) % 24;
const int curMinute = curHour * 60 + timeInfo->tm_min;
const int curSecond = curHour * 3600
+ timeInfo->tm_min * 60
+ timeInfo->tm_sec;
const int desiredSleepSeconds = SLEEP_DURATION * 60;
const int offsetMinutes = curMinute % SLEEP_DURATION;
const int offsetSeconds = curSecond % desiredSleepSeconds;

// align wake time to nearest multiple of SLEEP_DURATION
int sleepMinutes = SLEEP_DURATION - offsetMinutes;
if (offsetSeconds < 120
|| offsetSeconds / (float)desiredSleepSeconds > 0.95f)
{ // if we have a sleep time less than 2 minutes OR less 5% SLEEP_DURATION,
// skip to next alignment
sleepMinutes += SLEEP_DURATION;
}

if (extraHoursUntilWake == 0)
{ // align wake time to nearest multiple of SLEEP_DURATION
sleepDuration = SLEEP_DURATION * 60ULL
- ((timeInfo->tm_min % SLEEP_DURATION) * 60ULL
+ timeInfo->tm_sec);
// estimated wake time, if this falls in a sleep period then sleepDuration
// must be adjusted
const int predictedWakeHour = ((curMinute + sleepMinutes) / 60) % 24;

uint64_t sleepDuration;
if (predictedWakeHour < bedtimeHour)
{
sleepDuration = sleepMinutes * 60 - timeInfo->tm_sec;
}
else
{ // align wake time to the hour
sleepDuration = extraHoursUntilWake * 3600ULL
- (timeInfo->tm_min * 60ULL + timeInfo->tm_sec);
}

// if we are within 2 minutes of the next alignment.
if (sleepDuration <= 120ULL)
{
sleepDuration += SLEEP_DURATION * 60ULL;
const int hoursUntilWake = 24 - curHour;
sleepDuration = hoursUntilWake * 3600ULL
- (timeInfo->tm_min * 60ULL + timeInfo->tm_sec);
}

// add extra delay to compensate for esp32's with fast RTCs.
Expand Down

0 comments on commit f37e9e1

Please sign in to comment.