Closed lxrst closed 5 months ago
Great to hear! Thanks a lot!
I've looked into it a little further. I think I should be able to finish this by the end of the week.
That's awesome! Can't wait to test it out.
I'm so looking forward to this!
Likewise.
@lxrst , do NOT hesitate to ask me anything about a feature or aspect you have trouble to implement. I am sure choices will have to be made to cram as much feature as possible into the infinitime code but I would absolutely hate to waste some of your time if you made a call on your own that turned out to be questionable in the eyes of long time users. SleepTk is pretty simple in some aspect but quite advanced in others! I used it for literal years and have not changed the code for the last few, not ouf of laziness but because it was feature complete. Also I'm sure some parts of the code might be weird and I would gladly explain them.
As I'm writing this, the bounty is at $100 from me + up to $76 CAD from @Koloss0
Also, despite the name, the wakeup features are way more important than the tracking:
I'm so excited :)
Is SleepTK able to detect the different sleep phases? Or is it purely duration?
Hi,
So initially the plan was indeed to track the actual sleep cycle. But then I stumbled upon one paper that I think I linked in the bibliography. And the conclusion was that the main predictor of accuracy of a sleep tracker was actually just biasing with a clock. If I recall correctly, it was far better than any fusion of combination of sensors you could put on a watch. So I decided to remove this part of the code which had the benefit of greatly reducing the complexity as I was computing autocorrelations with reference signusoidal functions at some point for example.
But in the end I became aware that it was actually not needed at all because the average sleep cycle is roughly 90 minutes. And the biological tolerance for waking up refreshed is in the order of maybe 30 minutes. So if you have a very rough approximation of the current sleep cycle you're in then if you put slight vibrations to gently wake the user, it works.
What I mean is that I became confident that there was no way I could get a high confidence on estimating the sleep cycle and it became not important when wakeup features were stable.
Also something important to understand is that if the sleep cycle was disrupted during the night, then you are very quickly out of the envelope of the usual algorithms by other watches anyway.
The TLDR is that waking up with appropriate vibrations patterns is way more important than computing the sleep cycle. If the objective is to wake up feeling refreshed, that is. But if you're just interested in tracking your health, then you shouldn't rely on most consumer product algorithm at all nor mine I'd say.
That makes a lot of sense. I don't necessarily need any of the sleep phases, sleep duration would be sufficient if we want to maximize efficiency and whatnot.
What is important though is that the user gets to know:
Is there a feature to wake you up a set amount of hours (in a fitting sleep stage) after falling asleep?
Initially there was, but I removed that part too because I noticed that it was actually quite constant so it was better to leave that handled by the user to decide its own offset.
And in the case where the person takes really too long to get to sleep, then it makes sense to yourself think about setting the alarm again just like a regular alarm clock. It's better than over engineering a python app with so little ram.
Additionally, the natural wake feature can solve potential issues around this because you can set it to only wake you up if you are in a good part of the cycle by doing tiny vibrations every 30s etc
Hypothetically, let's say I go to bed at around 8pm and have to get up at 5:30am. If I start the sleep tracker at 8pm, will it accurately track my sleep duration even if it takes me, say, 1h to actually fall asleep?
Tracking can be disabled, or track motion or motion + heart rate. It's not telling you when you were asleep specifically. You'll just have the raw motion + hr data and can post process it however you like.
I did try and you might find some old commits that overengineered everything to try to infer sleep etc but concluded that it made no sense as a feature as it added a lot of noise and lines and above all a false sense of trust from the user to the algorithm which can't beat established companies algl that are themselves not satisfying compared to polysomnography (the current gold standard)
I plan on buying a colmi smart ring someday and use it to store my raw sleep data to gadgetbridge. But it can't vibrate obviously so it might be a nice setup to have both.
Also, keep in mind that the average sleeper sleeps at best 5 cycles per night. Each cycle get shorter and shorter as the night progresses. The cycle length decreaes with age. The hr drops samples and is not fully reliable on waspos. Alcohol, coffee, exercise, deeply impact some aspects of the cycles. External temperature too. Having a mosquito bite that makes your hand reach to scratch counts as motion. Having your significant other pull the sheets etc.
There's at lot of factors at play and with 5 datapoint per night I firmly concluded that it was over engineered and couldn't reasonnably expect a reliable accuracy, especially on out of distribution nights where it matters the most arguably (sleeping in a hotel?).
Wake up features on the other hand are an absolute gamechanger and with @lxrst 's work there's a chance it can be used by more than a few lone waspos geeks :)
I might just not understand correctly, and if so please tell me, but if it isn't telling me when I was asleep specifically, then what part of it is actually the sleep tracking part? Or is the entire thing mostly just an advanced wake up feature?
I concede that the name is at this point confusing. It started as what you imagine. But I removed the advanced stuff that tried to infer sleep quality and cycles, left raw data tracking (motion and hr), kept the advanced wakeup features.
So is it tracking your sleep ? Kinda. It can be tracking your body throughout sleep, which is what all other sleep trackers do. Arguably they just lie about telling you you had 87% SleepQualityPoints©
when in fact they did barely better than I did but are not honest about how that stuff works and how much bit we can infer about cycles with a wristworn device. Except polysomnography that actually defines sleep.
I am curious about your feelings about all this. I thought I was being quite explicit about all that in my messages and docs no?
Tldr: i thought tracking my sleep was what I needed to wake up well and recover efficiently but actually I was looking for advanced wakeup features all along.
Maybe so are you!
I understand that and looking at the docs, it makes sense. But the naming of "sleep tracker" implies things like sleep duration and tracking of sleep stages imo. Since I have fixed wake up times because of school, advanced wake up features would not be in my interest most days. I would rather wake up and know "Oh nice, I've actually slept 8hrs 18min this night, that's cool". I was thinking that would be trackable via drop of BPM and motion, and when your BPM falls under a certain threshold thats x BPM lower than before for x minutes, then you've most probably fallen asleep. But because of my limited knowledge and experience in these programming languages, I don't actually know how feasible that is.
Currently, I actually do what I would think a sleep tracker would do but manually.
I'll wake up to a HRM graph like this and then check when the first dip in BPM happened, when the first spike happened again (which is usually around 5:20 to 5:30 anyway) and then I know my sleep duration. It would just be nice to wake up and see that sleep duration on my watch immediately instead of having to go through all these steps.
@tituscmd Since I have fixed wake up times because of school, advanced wake up features would not be in my interest most days.
I'm getting slightly off-topic here, but it goes to use-case, your honour! 😅
AIUI the purpose of the smart wake features (certainly in SleepAsAndroid and I'm fairly confident SleepTk as well) is that if you have a fixed wake time there's no guarantee of which sleep phase you'll be in at that fixed time, and being woken during deep sleep leaves you feeling groggy and unrefreshed. So the idea is to wake you "at or before" that fixed time, by choosing a point where your sleep stage is conducive to feeling refreshed when awoken.
SleepAsAndroid does this by trying to detect when you are in a light sleep phase by tracking movement etc, and my impression is that SleepTk aims to do this by using the subtle "wrist-tap" alarm so that it wouldn't disturb deep sleep but will rouse you from light sleep (apologies if I am mis-characterising SleepTk, I am not yet a user).
So it's folk who have a "fixed wake commitment time" that stand to benefit most from smart-wake times because they don't have the luxury of just sleeping until they wake "naturally".
I've had DSPD (delayed sleep phase disorder) since I was a baby (and lots of folk have it temporarily from early teens to mid-late twenties), and it makes waking up to a morning alarm hell on earth. Apps like SaA or SleepTk would have been pretty handy in those first forty years for me, but alas, all I could do was set up ever-more impactful alarms, taking the nuclear arms race option for battling waking. My natural wake time was around 2pm. Schooling (and work!) was pretty rough.
Sorry - didn't mean to turn that into a pity party! Just that I wanted to point out where smart-wake can fit in with a fixed waking commitment, and also do a little awareness-building about DSPS/DSPD and circadian disorders, because GPs and many sleep specialists are still completely unaware of many of them, and sometimes hearing an "oh, that me" story is what it takes to get some answers.
I understand that and looking at the docs, it makes sense. But the naming of "sleep tracker" implies things like sleep duration and tracking of sleep stages imo. Since I have fixed wake up times because of school, advanced wake up features would not be in my interest most days. I would rather wake up and know "Oh nice, I've actually slept 8hrs 18min this night, that's cool". I was thinking that would be trackable via drop of BPM and motion, and when your BPM falls under a certain threshold thats x BPM lower than before for x minutes, then you've most probably fallen asleep. But because of my limited knowledge and experience in these programming languages, I don't actually know how feasible that is.
As a student finishing medical school my opinion is that you overestimate the usefulness of such a noisy metric. The errors bars are tremendous and likely only plausibly informative on very controlled nights. Lying in bed thinking already is a dip in the HR. You can have spikes because of dreams etc.
Personnaly I just set SleepTk at the last few minute before falling asleep and turn it off at wake so I treat the time of sleep as a maximum estimate and mentally adjust by just knowing if it took me more or less time than usual to fall asleep.
Also waspos has a bug with HR that infinitime does not. So using hr as a primary sensors was not an option.
Regarding the name, I considered changing it but it feels also off to not call it tracking because it is tracking sleep just not cycles. I am absolutely open to suggestions. BetterWaker?
Currently, I actually do what I would think a sleep tracker would do but manually.
I'll wake up to a HRM graph like this and then check when the first dip in BPM happened, when the first spike happened again (which is usually around 5:20 to 5:30 anyway) and then I know my sleep duration. It would just be nice to wake up and see that sleep duration on my watch immediately instead of having to go through all these steps.
Can you tell me over how long that dip happened? I'm suspecting still higher error bars than my technique I just outlined.
@tituscmd Since I have fixed wake up times because of school, advanced wake up features would not be in my interest most days.
I'm getting slightly off-topic here, but it goes to use-case, your honour! 😅
AIUI the purpose of the smart wake features (certainly in SleepAsAndroid and I'm fairly confident SleepTk as well) is that if you have a fixed wake time there's no guarantee of which sleep phase you'll be in at that fixed time, and being woken during deep sleep leaves you feeling groggy and unrefreshed. So the idea is to wake you "at or before" that fixed time, by choosing a point where your sleep stage is conducive to feeling refreshed when awoken.
So SAA does that. Sleeptk wanted intially to do that but it ended up a bad idea because waking up gradually achieves the same purpose in a better overall setup as I explained above in more depth.
SleepAsAndroid does this by trying to detect when you are in a light sleep phase by tracking movement etc, and my impression is that SleepTk aims to do this by using the subtle "wrist-tap" alarm so that it wouldn't disturb deep sleep but will rouse you from light sleep (apologies if I am mis-characterising SleepTk, I am not yet a user).
Close! This is only the NaturalWake feature. I use it when I want to sleep as long as I can while feeling refreshed on wake.
The other alarm type is a vibration pattern gradually increasing in strength and decreasing in intervibration delay. With all that customizable as a top level variable.
So it's folk who have a "fixed wake commitment time" that stand to benefit most from smart-wake times because they don't have the luxury of just sleeping until they wake "naturally".
For those nights I use the "not natural" wakeup mode I just described. Otherwise yeah spot on.
I've had DSPD (delayed sleep phase disorder) since I was a baby (and lots of folk have it temporarily from early teens to mid-late twenties), and it makes waking up to a morning alarm hell on earth. Apps like SaA or SleepTk would have been pretty handy in those first forty years for me, but alas, all I could do was set up ever-more impactful alarms, taking the nuclear arms race option for battling waking. My natural wake time was around 2pm. Schooling (and work!) was pretty rough.
I'm sorry to hear that. I'm optimistic it could help you, and opine that regular algorithms of sleep tracking would be out of their spec envelope for regular hours for the same reason tracking the sleep of someone without DSPD in the afternoon would be out of distribution.
Sorry - didn't mean to turn that into a pity party! Just that I wanted to point out where smart-wake can fit in with a fixed waking commitment, and also do a little awareness-building about DSPS/DSPD and circadian disorders, because GPs and many sleep specialists are still completely unaware of many of them, and sometimes hearing an "oh, that me" story is what it takes to get some answers.
Apologies not accepted, your clarifications were useful I think so thank you :)
Currently, I actually do what I would think a sleep tracker would do but manually.
I'll wake up to a HRM graph like this and then check when the first dip in BPM happened, when the first spike happened again (which is usually around 5:20 to 5:30 anyway) and then I know my sleep duration. It would just be nice to wake up and see that sleep duration on my watch immediately instead of having to go through all these steps.
Can you tell me over how long that dip happened? I'm suspecting still higher error bars than my technique I just outlined.
The image I posted is a bit older, so I can't tell you exactly how long the sleep duration was there (since I regularly clear my HRM data) but I remember those estimations of sleep durations of mine almost always overlapping with how long I remember laying in bed until I fell asleep.
Actually, I found one where I can give you the times exactly.
This was Oct 30th. My school day started later that day so I could sleep in a bit. The big dip started at around 00:00 and ended at around 10:00. I wen't to bed at 23:30 and set my alarm to 09:55, so these times make perfect sense and now I know almost exactly how long I slept that day.
Thanks, this might be relevant to sleeptk's infinitime version as the HR will be accurate there. If I recall correctly, the gadget bridge Android app supports a specifying specific sleep metadata through their api
I'd be very glad if the automatic equivalent of what I do with the graphs would be implemented into the sleep tracker. Don't hesitate to contact me if you need any HRM data like that again.
Thanks but as there is no way to send data to GB from waspos it's out of my hands, and into the eventual porter's.
Hi @lxrst are there any news on your side? As a reminder and IRC there's at least $174 waiting for you if you pull this off :)
The user @cyberneel created the issue #14 and asked the following:
@thiswillbeyourgithub I came across this from a bounty page and saw that you were more interested in the wake features than the tracking. I have a branch on my personal repo where I have been working on wake features more recently and got gradual wake along with snoozing to work on InfiniTime and am looking at implementing natural wake soon. I also have the framework for sleep tracking in place, just need to create the analysis part of the data. is this something you are interested in or is the bounty already taken?
To make it easy for anyone to follow along and avoid duplicate works and multiple bounty claiming, I decided to answer in this issue instead:
Hi! I have not heard from @lxrst so the bounty is definitely not taken!
Also just in case, I advise you to read this thread entirely.
Basically if everything specified in this message thread is indeed implemented in your app, you can definitely claim the bounty. If you do less features, you can still claim a proportion of the bounty but I have a lot more chances of disagreeing and will be the only person to decide (at least for my $50, I have a friend who staked $50 too and another user added CAD$76).
Can't wait to see it when you're nearing the end! Don't hesitate if you have any questions of course.
@thiswillbeyourgithub
I created a release on my repo for what I have so far, I would appreciate it if you could check it out and give me any feedback.
Thanks a lot, I'll try to flash it in a few hours. Can you provide a few pointers as to how I could modify the constants? For example related to gradual wake. In sleeptk the constants are all declared at the top.
Oh i just found this link so I think I can just recompile
@cyberneel sorry for the many messages but can you tell me what I should flash to go from waspos to infinitime? There's a surprising lack of info online as they're either possibly outdated or just assume that you have a stock watch (by default it already includes infinitime).
I think I can use waspos's ota dfu python script to flash the .bin file there then use siglo or gadgetbridge to flash your release.
Is that correct?
@thiswillbeyourgithub I updated my release notes and added instructions for the constants that are currently available.
Also, I personally build with these instructions but if you are familiar with docker that should work I think. But make sure you delete some apps since currently, the storage is slightly high with the other apps. The binary I included removes the paint app.
About flashing, I am not too familiar with switches OS but this doc seems to have some info. Let me know if that helps or not, I think there was another place with more info.
@thiswillbeyourgithub I updated my release notes and added instructions for the constants that are currently available.
Thanks a lot, the link is a 404 but I found the file.
I'll try flashing now
@thiswillbeyourgithub Oh lol I was merging and deleting branches so it must have broken. Let me know how it goes, I am about to release another file with some bug fixes I found this morning with the info screen.
@thiswillbeyourgithub Here is the new release by the way. Please use this one.
I initially followed this guide: https://pine64.org/documentation/PineTime/Software/Switching_between_InfiniTime_and_Wasp-os/#:~:text=To%20do%20this%2C%20flash%3A%20wasp-os-0.4%2Fbuild-pinetime%2Freloader-mcuboot.zip%20After%20flashing%2C%20it,cone%29%2C%20and%20then%20it%E2%80%99ll%20boot%20the%20wasp-os%20bootloader.
use ota-dfu from waspos to flash the recovery file:
./tools/ota-dfu/dfu.py -z ../infinitime/infinisleep/reloader-infinitime-recovery-0.14.1.zip -a MAC_ADDRESS --legacy
This seemed to work fine.
Then after a while I finally understood how to get the pineapple to be red and make the watch ready to accept the infinitime zip.
Then tried the same with flashing the mcuboot from infinisleep at https://github.com/cyberneel/InfiniTime/releases:
./tools/ota-dfu/dfu.py -z ../infinitime/infinisleep/pinetime-mcuboot-app-dfu-1.14.0.zip -a MAC_ADDRESS --legacy
I continually got error : Checking DFU State... Exception at line 163: UUID not found: 8ec90001-f315-4f60-REDACTED-REDACTED
I also failed to get gadgetbridge to upload it.
Then finally tried again with the dfu.py from infinitime (instead of the one from wasp-os) and finally I'm getting something that looks like an upload in progress. The full command was: python dfu.py -z ../../../infinisleep/pinetime-mcuboot-app-dfu-1.14.0.zip -a MAC_ADDRESS --legacy
Regarding the app it looks super promising. It's not a good timing for me to spend too much time on this right now so I'll try and test it out and tell you my thoughts if that's okay. One of my first remarks is that there does not seem to be an automatic computation of suggested alarm time. When you open sleeptk, the default alarm time suggested is by default what the user probably needs, see lines after this one: https://github.com/thiswillbeyourgithub/SleepTk_pinetime_sleep_tracker/blob/5e64aecdc95c4c0c55d1e8b3b2ca9b8d341c78ae/sleep_tk.py#L459
Overall it's suuuuper promissing
@thiswillbeyourgithub I forgot to update the link to that file, it should work now. I'll look into the alarm suggestion next and update you on that. The bounty is a good motivator lol. Thanks for your support.
The bounty is a good motivator lol.
Not gonna lie, you're definitely on the right path and a good part of the way there :)
@thiswillbeyourgithub More progress! Here is a release with the suggested alarm time, it was a pretty simple thing so went quickly.
Great.
Don't mistake my lack of words for lack of enthusiasm i'm just in a hurry:
@thiswillbeyourgithub No worries about the short texts.
edit: Can you explain what you experienced, I quickly tried this on my watch and it seems that when I tap the screen after it turns off, it opens up to the sleep app.
No, the wake-up alarm is independent of the tracking. You should still be able to track by pressing start if the alarm is off. It should say alarm not set on the screen.
That is how many gradual wake intervals are left. I thought it may be useful to quickly see how many nudges you have until you have to wake up.
I was letting the app run in a simulator and found a stupid bug caused by incorrectly subtracting time. I fixed it long with a bug where the current sleep cycles were not properly displayed here
Can you explain what you experienced, I quickly tried this on my watch and it seems that when I tap the screen after it turns off, it opens up to the sleep app.
What I mean is that if you exit the sleeptk app, even though it is still running, then if you wake the watch from the suspend, you will not be forcibly starting inside sleeptk like I do on waspos. So, in effect, when waking from suspend, you will arrive at the original clock. Which is not in red. I can totally imagine that it could very much over complicate things to get this to work, but I just wanted to voice it just in case it was actually not that hard to do.
No, the wake-up alarm is independent of the tracking. You should still be able to track by pressing start if the alarm is off. It should say alarm not set on the screen.
Yeah, I understand that I just meant that I don't want to have the gradual wake up feature waking me up even though I disabled the alarm clock just because sleeptk was still running.
That is how many gradual wake intervals are left. I thought it may be useful to quickly see how many nudges you have until you have to wake up.
I'm not convinced but I don't really mind I think. What seems more important to me is the fact that it displays how far you are into the night which can be used to understand why you have insomnia. I don't remember if you added it already or not.
Also did you make sure that the number of push of the button you had to use to disable the clock was reset every time the screen turned off?
Can you explain what you experienced, I quickly tried this on my watch and it seems that when I tap the screen after it turns off, it opens up to the sleep app.
What I mean is that if you exit the sleeptk app, even though it is still running, then if you wake the watch from the suspend, you will not be forcibly starting inside sleeptk like I do on waspos. So, in effect, when waking from suspend, you will arrive at the original clock. Which is not in red. I can totally imagine that it could very much over complicate things to get this to work, but I just wanted to voice it just in case it was actually not that hard to do.
Ah, I see what you mean. I can use InfiniTime's system events to check if the infinisleep controller is running to force go to that screen. I think it is simple, but I will play around with it.
No, the wake-up alarm is independent of the tracking. You should still be able to track by pressing start if the alarm is off. It should say alarm not set on the screen.
Yeah, I understand that I just meant that I don't want to have the gradual wake up feature waking me up even though I disabled the alarm clock just because sleeptk was still running.
The gradual wakes are ONLY triggered when the alarm is active. So tracking should not trigger ANY gradual wake. I can make it so that the gradual wake shows as "not set" when the alarm is off.
That is how many gradual wake intervals are left. I thought it may be useful to quickly see how many nudges you have until you have to wake up.
I'm not convinced but I don't really mind I think. What seems more important to me is the fact that it displays how far you are into the night which can be used to understand why you have insomnia. I don't remember if you added it already or not.
Right now you can see ongoing sleep time and the equivalent cycles.
Also did you make sure that the number of push of the button you had to use to disable the clock was reset every time the screen turned off?
Lol, I realized I overlooked this earlier this morning. I coded a fix for it earlier today and will put that up soon with some other minor updates. I couldn't figure out how to run the reset when the screen turns off, so I made a timer that resets the count after 2 seconds of no presses. I might make this a constant so you can adjust the timeout to your liking.
Sorry, I'd forgotten about this. I haven't put much work into it yet, but I'm able to start working on this now. I'll post updates as soon as I have something.