Bangle.js: Fetch activity data #3212
No reviewers
Labels
No labels
device mi band 7
activity post processing
activity/health
Android 12
Android 13
android integrations
architecture
Bangle.js
bug
changes requested
charts
deprecation notice
details not provided
developer documentation
device amazfit band 5
device amazfit bip
device amazfit cor
device Casio
device fossil
device garmin
device gtr 2e
device gts 2 mini
device h30
device hplus
device huami
device Huawei
device liveview
device mi band
device mi band 2
device mi band 3
device mi band 4
device mi band 5
device mi band 6
device no.1 f1
device pace
device pebble
device pebble 2
device pinetime infinitime
device request
device sony
device support
device watch 9
device xiaomi
discussion
documentation
duplicate
enhancement
feature request
Gadgetbridge
good first issue
help wanted
i am developing my own app can you help
icebox
intent api
internationalisation
invalid
needs work
network companion app
new device
no feedback
not a bug
notifications
one of the 1000 issues about disconnection
pairing/connecting
potentially fixed / confirm and close
question
research
security
seems abandoned
Solved, waiting for F-Droid release
suggest to close
task
user interface / UX
wear os
weather
wontfix
Zepp OS
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: Freeyourgadget/Gadgetbridge#3212
Loading…
Reference in a new issue
No description provided.
Delete branch "jr-bangle-activity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Implement activity fetching from the Bangle.js health app:
TODO:
PR on BangleApps: https://github.com/espruino/BangleApps/pull/2889
Bangle.js: Fetch activity datato WIP: Bangle.js: Fetch activity data@gfwilliams I was playing around while trying to understand how the Bangle works, and actually missed
d82ba7a04c
, I looked around and could not find anything fetch-related..There does not seem to be any code to handle it on BangleApps, but I can refactor this to work some other way.
Could a situation come about where where we have a gap in data sent to gadgetbridge but the last fetch timestamp is newer then that gap so it doesn't get filled?
I guess that's possible. There's a button to set the last activity fetch timestamp in the debug activity, but we do need some logic to make this more resilient (eg. the bangle reporting how many items it sent, and if there's a mismatch, GB does not persist the new timestamp).
Thanks! Yes, I started this in Gadgetbridge and then didn't get around to the Bangle.js bit before my holiday.
For the timestamp, is it safer just to use what was done in
d82ba7a04c
- so looking at the last recorded activity item? So then even if a sync failed we don't risk getting duplicate items?When connected normally the Bangle should send updates every 10 minutes so what we really care about is making sure that when we next reconnect we catch up with those.
In terms of doing long-term syncing (so catching up on data from before this PR gets merged), I'm not sure just having a single sync date var is good enough.
What I'm concerned about is that there will probably be some health records from when Gadgetbridge was connected (and the timestamp on those won't be exact as it's from when Gadgetbridge received the record), so when you do a sync right from the start of recorded time you'll end up with a whole bunch of duplicate records, which will then double the amount of recorded steps on all those days.
For a full sync, I think we want to iterate over all the health records Gadgetbridge has, and, when we see any records that are > ~15 minutes apart we ask Bangle.js to search and fill in the time period inbetween?
@gfwilliams just a couple of statements/questions to ensure my assumptions are correct:
I was thinking it might be easier / more robust to request the full database at first sync (last sync timestamp in Gadgetbridge == 0), then reconcile the entire database. It should be a one-time thing, but it's not yet clear if it would take too long for users that have had the bangle for a while. This would allow us to sync samples older than the earliest sample we get on Gadgetbridge too.
I am not sure I get this. Are you referring to the case where in the long-term we continue sending the real-time samples, and we still get gaps in the data?
Yes.
Yes.
Exactly - I haven't checked, but I'd say a few seconds - definitely less than a minute!
The file in storage is the last full sample (so the previous 10 minute window). You can use
Bangle.getHealth...
to get the current one but we don't want to do that normally as it won't contain complete data.In 'realtime' mode (https://codeberg.org/Freeyourgadget/Gadgetbridge/src/branch/master/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/banglejs/BangleJSDeviceSupport.java#L1290-L1292) you get much more often data reported to you, and the Bangle's 'health' library isn't involved and doesn't save that more detailed info on the Bangle either.
As you note in the code comment, it'll cause step over-counting so I guess we need to keep track of realtime steps and then subtract them from the 'health' event we get. Maybe Bangle.js needs to add
rt:true
to realtime data to make it easier (maybe it should even be a different event name?).Assuming someone's had their Bangle for a year (many had it since the KickStarter so getting on for 2 years now): 6/hr * 24 * 365 * 20 bytes = 1mb transfer
The actual transfer speed depends a bit on the device, but we're looking at probably over a minute of tranfers? It's quite a lot to block the device for (especially if there is no indication shown) and I don't think is something we'd want to do automatically on first connect as it could provide quite a bad experience.
I just meant someone might have run Gadgetbridge for a while previously so they already have at least some data in it, but then they upgrade and get this code and they sync. In that case we'll be sending a lot of data that has already been gathered.
Plus if someone deleted their Gadgetbridge health data somehow (is it even possible) if the sync date hadn't been reset they would have no way of re-syncing to get the data back.
Anyway, it's not a big deal - I just felt like having Gadgetbridge being able to figure out where it had gaps in the data would be neat, but I guess it has issues - if the user routinely turns their Bangle off then there might be many gaps that Gadgetbridge has to request to be filled in.
We just have to watch out for de-duplicating data in Gadgetbridge - not accepting any duplicate data that arrives within 1 minute of each 10 minute chunk (unless it's realtime).
Okay, cool - this makes it easier.
Yup... but this is starting to get more complex than I would have otherwise thought and like :)
I don't think that in Huami devices we persist the real-time steps, we just broadcast them for the real-time steps activity data. Should we stop persisting them? Then we will just have to worry about the gaps in the data going forward (we still need to take them into account for the first sync).
This is a good point. This does not happen on first connect, activity data syncing is a separate operation, and there is an indication in Gadgetbridge, but not on the device.
There is currently a button in the debug activity to set the activity fetch timestamp, so it's possible to go back and re-sync.
In the worst cases, I'm expecting there to be a lot of gaps on the data, requesting these one by one and ensuring that everything is consistent at the end will be tricky, I need to think about this a bit more.
Follow-up questions:
Ok, sounds good having the last sync date then...
Yes, that sounds like a great idea! So we just need an
rt:true
in https://github.com/espruino/BangleApps/blob/master/apps/android/boot.js#L196Yes
No - so best to just mark the realtime data as realtime and ignore it on Gadgetbridge - should be backwards compatible too
@gfwilliams what if we start syncing from the current timestamp once this is released in Gadgetbridge, but allow the user to trigger a full sync from the device preferences? Clicking it would warn the user that it might take a while, as well as display the progress. GB would fetch the full data from the Bangle, and persist in the Gadgetbridge database as needed, taking into account any gaps or already existing data.
That sounds perfect to me, thanks!
7219dd17af
to795a44c748
Closes #3133 I believe
Looks good to me! Is
sampleBuffer
needed? It seems to be defined in the last commit but I don't see it used.Also, is
onFetchRecordedData
called automatically when the Bangle is connected? It would be really good to be able to ensure that without having to click 'fetch', if there were activity samples while the Bangle was disconnected, they are automatically synced (at least if it's just a day's worth or so that'll be caught up in a fraction of a second)@gfwilliams this is still incomplete, i still need to work on the de duplication. I'll try and finish in a couple of days once I'm back.
I pushed some work-in-progress code, the sample buffer will eventually be needed, but not yet being used.
38d8b8b271
to74e5f8d369
Updated PR to match the latest changes in BangleApps.
I have not yet tested this extensively, but should be working and at least sync new data.
It should now only be missing deduplication of samples and testing.
I was thinking of buffering the data, cross-checking the count of samples at the end, and not persist the timestamp if there is a mismatch (eg. some packet failed to be parsed or lost). I will be removing this for now.
Not right now, it is either called:
However, I don't see why we could not call this on connection, so I will add that.
74e5f8d369
to8c9c656607
WIP: Bangle.js: Fetch activity datato Bangle.js: Fetch activity dataBangle.js: Fetch activity datato WIP: Bangle.js: Fetch activity dataAdded de-duplication of samples, this PR should be mostly ready. However, the realtime samples are offset by 10 minutes when compared with the duplicates. Discussion started in the BangleApps PR.
Great! Thanks for all your work on this.
I guess this is good to go now - the 10 min offset is something that we should definitely handle on the bangle.js side
8c9c656607
tod4b4cb6a07
WIP: Bangle.js: Fetch activity datato Bangle.js: Fetch activity datad4b4cb6a07
toa95820d09e