Feature/gadgetbridge sleep as android
This PR adds a bootloader which sends HRM and accelerometer data to Gadgetbridge for usage with the Sleep as Android integration. Feedback is greatly appreciated.
Looks good to me - might be worth mentioning in the readme that this app doesn't drive the HRM, so the user might want to adjust the HRM interval in their bangle's settings to the interval they'd like. Although that might be obvious? I can merge once you're happy with this either way though :)
(also - the title has "WIP", I guess it's no longer?)
Hey @bobrippling, first of all thanks for your fast response :-). The WIP is right. I haven't written the README yet. I just copied the folder I used for the GATT HRM exposure. I will update the README and ping you once it's ready, okay?
Further, the Gadgetbridge part - although seemingly working- isn't merged yet. I hacked everything together last night. Do you think the approach I chose is the right one? I don't have much experience in embedded development. So I'm not entirely sure whether my approach could be more battery-friendly.
Thanks again!
Hey @bobrippling, first of all thanks for your fast response :-). The WIP is right. I haven't written the README yet. I just copied the folder I used for the GATT HRM exposure. I will update the README and ping you once it's ready, okay?
Sounds good, no rush! I'll mark this as a draft in the meanwhile
Further, the Gadgetbridge part - although seemingly working- isn't merged yet. I hacked everything together last night. Do you think the approach I chose is the right one? I don't have much experience in embedded development. So I'm not entirely sure whether my approach could be more battery-friendly.
Not a problem, it seems @joserebelo knows enough to take care of that side of things :)
Hey @bobrippling and @joserebelo, I added a feature for starting/stopping the reporting. For this, I created an event inside the android.boot.js called "sleepasandroid". The event receives a boolean (enable true/false) and writes the state to the settings file. After writing, the load() function is called to reload the watch.
I also implemented the event In my Gadgetbridge PR. Is this a good way to do it?
Thank you!
@AnotherStranger I don't think this should be branded as "Sleep as Android" on the Bangle side. All we need is to be able to toggle real-time accelerometer from Gadgetbridge, which may even be useful for other use-cases.
I'd recommend adding an "accel" request, with a on/off switch, which would report the accelerometer values to Gadgetbridge with a similar "accel" event. We can probably keep the heart rate being reported separate, as I believe that already happens when there is a measurement, and if I recall correctly, we receive the hr values in the "act" events.
Regarding how to properly do this on the Bangle side, I am not super experienced with the structure as well, so I am not sure whether this needs a separate app or if it could simply be done in the android boot code.
@joserebelo Yeah, you're right! I was too focused on the Use Case I tried to implement for myself ;-). I will refactor this to a more generic branding and will update my Gadgetbridge PR as well.
My proposal is:
- Expose all fields we receive from the accel event
- Make the interval configurable from Gadgetbridge (I would as first step hardcode it on the side of GB though)
- Rename everything to a more generic and suiting name. (Suggestions welcome)
As a side note: I tested the tracking for two nights using Sleeps as Android and it seems to work well.
Are you okay with this?
Hey @joserebelo and @bobrippling, I think this PR is ready. @joserebelo The Gadgetbridge Implementation and the Bangle App are ready, right? Or is there Anything I missed?
I also tested the integration again last night and the measurements seem to work and are reported to Sleep as Android.
Thank you for your patience and guidance!
The changes look good - one small question that's perhaps more for yourself and @joserebelo, would it be beneficial to bundle the accel data into the "act" event, so they go with the HRM values? Or do you prefer a separate event for accel data?
The changes look good - one small question that's perhaps more for yourself and @joserebelo, would it be beneficial to bundle the accel data into the
"act"event, so they go with the HRM values? Or do you prefer a separate event for accel data?
Hey @bobrippling,
-
I think bundling would make sense. However, Sleep as Android requires one accel event every 10 seconds. If we wanted to integrate this, we needed to send the act event every 10 seconds once we activated Sleep as Android.
-
Concerning the accelsender event and load call, I chose this way because I thought it wouldn't be a great idea to put functions into the global namespace. However, I'm not very experienced with Banglejs, so I will rely on your informed decision and happily implement either version.
- I think bundling would make sense. However, Sleep as Android requires one accel event every 10 seconds. If we wanted to integrate this, we needed to send the act event every 10 seconds once we activated Sleep as Android.
That's a fair point, let's keep them separate now in that case
- Concerning the accelsender event and load call, I chose this way because I thought it wouldn't be a great idea to put functions into the global namespace. However, I'm not very experienced with Banglejs, so I will rely on your informed decision and happily implement either version.
We could bring this in later if you didn't like the delay of loading again to apply settings, but as-is is ok :)
Kinda late to the party, but this sound that it can also enable other actions on Sleep As Android that couldn't be achieved with my initial PR in mi band since the watch doesn't send those data.
I did included methods in gadgetbridge for sending alarm actions like snooze and dismiss from watch, plus tracking controls. https://codeberg.org/Freeyourgadget/Gadgetbridge/src/commit/c9326ca4470581a1d0a4ce710c04ffafc0e41164/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/SleepAsAndroidSender.java#L448
Documentation on how those methods are supposed to be called
https://sleep.urbandroid.org/docs/devs/wearable_api.html#commands-from-watch