Conversation
tadelv
left a comment
There was a problem hiding this comment.
Two required fixes before this is in line with the repo guidance:
- The PR template hard gate is currently broken. The checked Contributor Responsibility line dropped the
<!-- contributor-responsibility -->marker from.github/pull_request_template.md, so theContribution policyworkflow is failing and the analyze/test work is being skipped. Please restore the template marker and get the required CI checks green. - There is a connection-lifecycle race in
TimemoreDotScale.onConnect(); see the inline comment. Please add a regression test for disconnect-during-init.
Additional guideline findings from the audit:
CONTRIBUTING.mdrequires issue-first development for external contributors. The feature commit (abf6e0f, 2026-08-30 16:18:30Z) predates issue #737 (created 16:21:58Z), and the issue itself says the implementation was already ready. That process requirement was not followed; this is not retroactively fixable, but should be observed for future contributions.- The implementation commit subject (
Add Timemore Dot BLE scale support) is not a Conventional Commit as required byCONTRIBUTING.md. Please reword it to the repo convention (for examplefeat(scale): add Timemore Dot BLE scale support).
Otherwise, the PR is well aligned with the device/BLE rules: it keeps third-party BLE details behind the transport abstraction, uses long UUIDs for BLE operations, catches DeviceNotConnectedException in the lowest-level scale write helper, adds focused tests, and updates the relevant device/BLE documentation.
| } | ||
| await _registerNotifications(); | ||
| await _initScale(); | ||
| _connectionStateController.add(ConnectionState.connected); |
There was a problem hiding this comment.
This can publish a stale connected state after the transport has already disconnected during the mandatory init delays. The disconnect listener sets the controller to disconnected, but _write() swallows DeviceNotConnectedException, _initScale() therefore completes, and this line overwrites the state back to connected. ScaleController.connectToScale() trusts the scale's state after onConnect(), so it can install a dead scale. Please verify the connection is still in the connecting generation/state before publishing connected (the Atomheart scale has this guard), and add a regression test that disconnects during init.
fe8fa56 to
9d3aaf3
Compare
|
All three points addressed in 1. Connect race — 2. Regression test — added 3. Commit message — reworded to 4. PR body — restored the Also hardware-verified on macOS: connect, disconnect cleanup, and weight feed recovery after a scale power-cycle all behave correctly. The PR checks workflow doesn't appear to have re-run after the push — likely needs approval for the fork run. Could you re-trigger when convenient? |
Summary
Add support for the Timemore Dot scale, a compact BLE-only scale from Timemore with no screen and no buttons — all interaction happens over Bluetooth. Pairing is initiated by a long press on the button on the bottom of the scale until the white LED flashes rapidly; a slow flash means it is waiting for a connection, and a solid LED means connected.
What this PR adds:
TimemoreDotScaleimplementation (serviceFFF0, weight notifications onFFF1, commands onFFF2) with itsA5 5Aframed protocol, ported from a reference driver verified against a physical Dottest/timemore_dot_protocol_test.dartdot/tes017, plus nameless advertisements carrying the FFF0 service (the Dot can advertise without a name outside pairing mode)DeviceImplementation,DeviceMatcher,DeviceFactory, and the discovery serviceOne hardware finding worth noting: notification frames from the Dot are not CRC-validated — captures from a physical unit show the two-byte frame tail stays
0x0000across every weight/timer value, i.e. the firmware never emits a real CRC. Sending commands does require CRC16/MODBUS, and the seven verified command frames are locked in by tests.Linked Issue
Fixes #737
Verification
flutter analyze: no issuesImpact
doc/AI_BLE_NOTES.md(protocol, CRC finding, connect sequence) anddoc/DeviceManagement.md(nameless-advertisement matching)Contributor Responsibility
AI-assisted development is allowed. The submitter remains responsible for the submitted work.