You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
0.9.29 - recovery/sleep miscalculated almost daily #448
Almost every day I'm fighting with sync times for an accurate sleep record/recovery score; I wake up, it hasn't fully synced yet, so I get the wrong recovery score and incomplete sleep data until syncing and then recalculation completes.
It'd be such a better daily user experience if there was the option to set a wakeup time (7AM in my case) and these two areas of the app:
would show a loading/syncing icon until the app has caught up to that wakeup time and then the sleep and recovery calculation are kicked off. Otherwise I'm dealing with inaccurate data every day until syncing is done (which in some cases is 4-5 hours after I wake up)
Steps to reproduce
Wear the band overnight
Check it in the morning
Note that sleep/recovery has already calculated even though syncing hasn't caught up to wakeup time
App version
0.9.29
Platform
Android (APK)
Phone model and OS version
Moto G power 2022 - Android version: 12 S3RQS32.20-42-10-9-12
Which band?
WHOOP 4.0
Screenshots
No response
Quick checks
The official WHOOP app is not also connected to this band
But if the data hasn't synced then it is incredibly unlikely that the calculation would be accurate.
Is the expectation that a "wake time" would count as a place to automatically try and sync the data if the app is running?
Just trying to understand more clearly what you mean or what is expected as this seems like an interesting area.
True
No, the wakeTime is to be tested against the dataSyncedUpToTime; when the dataSyncedUpToTime is greater than or equal to the wakeTime, then the recovery and sleep stats calculations can be started. Pseudocose example:
if (!hasRecoveryRun &&
!areSleepStatsCalculated &&
dataSyncedUpToTime >= wakeTime
) {
hasRecoveryRun = true
areSleepStatsCalculated = true
runRecoveryCalculation()
runSleepStatsCalculations()
} else {
// Check again after next update to the dataSyncedUpToTime variable
}
This ensures the sleep stats and recovery aren't recalculating repeatedly as syncing is bringing in more sleep data, instead it's waiting until all sleep data is brought in then running the calculations. It's only recalculating on days when the user sleeps in or if the user doesn't set a regular wake up time.
Many thanks for the clarification question, appreciate it 👍
Version 0.11.3 fix worked perfectly! Didn't send me a notification until it had synced all the way up to my regular wake time and only sent that one notification. Thanks @abdulsaheel!
Activity
gentbot commentedon Sep 22, 2026
But if the data hasn't synced then it is incredibly unlikely that the calculation would be accurate.
Is the expectation that a "wake time" would count as a place to automatically try and sync the data if the app is running?
Just trying to understand more clearly what you mean or what is expected as this seems like an interesting area.
cb0806151 commentedon Sep 22, 2026
True
No, the wakeTime is to be tested against the dataSyncedUpToTime; when the dataSyncedUpToTime is greater than or equal to the wakeTime, then the recovery and sleep stats calculations can be started. Pseudocose example:
This ensures the sleep stats and recovery aren't recalculating repeatedly as syncing is bringing in more sleep data, instead it's waiting until all sleep data is brought in then running the calculations. It's only recalculating on days when the user sleeps in or if the user doesn't set a regular wake up time.
Many thanks for the clarification question, appreciate it 👍
Merge OpenStrap#506 (sweep-r3-edge-main-1); main's overnightSettled (O…
cb0806151 commentedon Oct 14, 2026
Version 0.11.3 fix worked perfectly! Didn't send me a notification until it had synced all the way up to my regular wake time and only sent that one notification. Thanks @abdulsaheel!
feat(seam): port upstream's read changes into our seam
fix(derive): recovery-ready after every pass; a heavy job holds the q…
test(derive): recovery-ready is considered after light passes too (D16,
test(step2): regenerate the P2.3 and P2.5 goldens for the merged inputs