Skip to content

fix(bluetooth): mark bf500 history and convert imperial standard masses - #1553

Merged
oliexdev merged 2 commits into
oliexdev:masterfrom
michidk:feat/bf500-history-sync
Oct 17, 2026
Merged

oliexdev merged 2 commits into
oliexdev:masterfrom
michidk:feat/bf500-history-sync

Conversation

@michidk

@michidk michidk commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

The BF500 already syncs readings stored while offline on master: during consent it pushes them as normal 2A9D/2A9C indications (weight, then composition), and the standard profile saves them with their original timestamps. Captured with the unpatched 3.1.3 release:

← 2A9D  0E EC 36 EA 07 0A 11 0F 0A 1C 01 EB 00 C2 06   70.3 kg, taken 15:10:28 while disconnected
← 2A9C  98 03 00 00 CE 1A 00 00 00 00 00 00 00 00      no body analysis
   → published and saved
← 2A9F  20 02 01                                        consent success

So this PR no longer adds BF500-specific assembly. What's left:

  • feat: advertise HISTORY_READ for the BF500, so the generated support table stops listing its history as unavailable. The capture above is added to the weigh-in tests.
  • fix: masses in standard weight and body-composition packets with the imperial flag are 0.01 lb, but were stored as kilograms at that resolution (150 lb was saved as 150 kg). They are now converted to kilograms.
  • fix: a Date Time with year, month or day 0 means "not known", and the lenient calendar rolled impossible dates such as month 13 into another date. Such readings are now left without a timestamp.

The imperial and timestamp cases come from the GATT spec, not from a capture of a misbehaving scale; each has a test that fails on master.

All 891 unit tests pass, including the captured weigh-ins in StandardWeightProfileHandlerTest and BeurerSanitasHandlerTest.

Replaces #1545, whose source fork was deleted.

🤖 Generated with Claude Code

@oliexdev

Copy link
Copy Markdown
Owner

Before going further: is the weight-only loss actually observed? Every real capture I could find —
70 weigh-ins over ten models of this family, including the BF500 live weigh-in from #1034 —
sends a weight packet followed by a composition packet, and a weigh-in without foot contact still
gets an all-zero composition packet (BF720, #789). That sequence already works on master.

Could you attach an openScale log of one stored-reading sync with an unpatched build (release
or master, file logging on)? The received data chr=00002a9d… and chr=00002a9c… lines show the
order in which the BF500 sends them.

@michidk
michidk force-pushed the feat/bf500-history-sync branch from d88e4bf to e939e6e Compare October 17, 2026 13:05
michidk and others added 2 commits October 17, 2026 15:27
Standard weight and body-composition packets with the imperial flag carry
masses in 0.01 lb, but they were stored as kilograms at that resolution,
so a 150 lb reading was saved as 150 kg. Convert them to kilograms.

A Date Time with year, month or day 0 means "not known", and the lenient
calendar rolled impossible dates such as month 13 into another date.
Leave such readings without a timestamp instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The BF500 pushes readings taken while offline as normal 2A9D/2A9C
indications during consent, and the standard profile already saves them
with their original timestamps. Advertise HISTORY_READ so the support
table stops listing history as unavailable, and add the captured stored
reading to the weigh-in tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@michidk
michidk force-pushed the feat/bf500-history-sync branch from e939e6e to 02b12b3 Compare October 17, 2026 13:30
@michidk michidk changed the title feat(bluetooth): support BF500 stored measurement sync fix(bluetooth): mark bf500 history and convert imperial standard masses Oct 17, 2026
@michidk

michidk commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

You were right, thanks for pushing back on this.

I captured a stored-reading sync with the unpatched 3.1.3 release (file logging on). I weighed myself while the phone was disconnected, then reconnected. During consent, the BF500 sent that reading as a weight followed by an all-zero composition, and openScale saved it with its original timestamp, before the consent response even arrived:

← 2A9D  0E EC 36 EA 07 0A 11 0F 0A 1C 01 EB 00 C2 06   70.3 kg, taken 15:10:28 while disconnected
← 2A9C  98 03 00 00 CE 1A 00 00 00 00 00 00 00 00      no body analysis
   → published and saved
← 2A9F  20 02 01                                        consent success

So master already handles BF500 history. The "two weights in a row get merged" problem I described came from reading the merge code, not from anything the scale actually does. I had only tested offline sync with my patched build, so I never noticed the release already worked. The one real problem in that log is LBM = bone = 70.3 kg, which is #789 and already fixed by your 811926e.

I've cut the PR down to what still adds something, as two separate commits so you can take either one:

  1. feat: mark the BF500 as supporting history. The support table currently lists BF500 history as unavailable, which is how I ended up here. The capture above is added as a row in your StandardWeightProfileHandlerTest.

  2. fix: two corrections in the standard decoder, based on the GATT spec, not on a scale I saw misbehave:

    • Imperial masses are 0.01 lb but were stored as kg (150 lb was saved as 150 kg). They're now converted.
    • Timestamps: a year, month or day of 0 means "not known", and the lenient calendar rolled impossible dates like month 13 into a different date. Such readings are now saved without a timestamp instead.

    Each has a test that fails on master.

The BF500 assembler, the shared-decoder refactor and the protocol doc are gone. All unit tests pass. If you'd rather not have the decoder fixes, or the flag, tell me and I'll drop that commit.

@oliexdev
oliexdev merged commit d2955ae into oliexdev:master Oct 17, 2026
@oliexdev

Copy link
Copy Markdown
Owner

Merged, thanks for checking with the unpatched build and cutting the PR down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants